fancy 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. data/README.md +14 -14
  2. data/Rakefile +16 -4
  3. data/bin/fancy +3 -0
  4. data/bin/fspec +20 -0
  5. data/bin/fyi +27 -11
  6. data/bin/ifancy +1 -1
  7. data/boot/fancy_ext.rb +1 -0
  8. data/boot/fancy_ext/block_env.rb +1 -9
  9. data/boot/fancy_ext/delegator.rb +64 -0
  10. data/boot/fancy_ext/object.rb +4 -0
  11. data/boot/fancy_ext/thread.rb +4 -0
  12. data/boot/load.rb +5 -1
  13. data/boot/rbx-compiler/compiler/ast.rb +0 -1
  14. data/boot/rbx-compiler/compiler/ast/class_def.rb +2 -0
  15. data/boot/rbx-compiler/compiler/ast/method_def.rb +2 -0
  16. data/boot/rbx-compiler/compiler/ast/node.rb +10 -0
  17. data/boot/rbx-compiler/compiler/ast/ruby_args.rb +12 -0
  18. data/boot/rbx-compiler/compiler/ast/singleton_method_def.rb +2 -0
  19. data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
  20. data/boot/rbx-compiler/parser/lexer.lex +5 -11
  21. data/boot/rbx-compiler/parser/parser.rb +16 -5
  22. data/boot/rbx-compiler/parser/parser.y +39 -24
  23. data/doc/api/fancy.css +1 -1
  24. data/doc/api/fancy.jsonp +1 -1
  25. data/doc/api/fdoc.js +22 -4
  26. data/doc/api/index.html +5 -6
  27. data/doc/api/jquery-ui.min.js +401 -0
  28. data/doc/api/jquery.tools.min.js +192 -0
  29. data/doc/api/themeswitchertool.js +250 -0
  30. data/doc/features.md +17 -0
  31. data/examples/actor_bunnies.fy +32 -0
  32. data/examples/actors.fy +26 -0
  33. data/examples/actors_primitive.fy +27 -0
  34. data/examples/actors_ring.fy +37 -0
  35. data/examples/armstrong_numbers.fy +1 -1
  36. data/examples/array.fy +7 -9
  37. data/examples/async_send.fy +1 -2
  38. data/examples/blocks.fy +4 -4
  39. data/examples/call_with_receiver.fy +1 -1
  40. data/examples/class.fy +1 -1
  41. data/examples/default_args.fy +4 -1
  42. data/examples/define_methods.fy +2 -2
  43. data/examples/echo.fy +1 -1
  44. data/examples/factorial.fy +1 -1
  45. data/examples/future_composition.fy +2 -2
  46. data/examples/futures.fy +0 -5
  47. data/examples/game_of_life.fy +1 -1
  48. data/examples/person.fy +1 -1
  49. data/lib/argv.fy +7 -2
  50. data/lib/array.fy +109 -42
  51. data/lib/block.fy +39 -14
  52. data/lib/boot.fy +2 -0
  53. data/lib/class.fy +2 -0
  54. data/lib/compiler/ast.fy +2 -1
  55. data/lib/compiler/ast/assign.fy +2 -3
  56. data/lib/compiler/ast/async_send.fy +1 -15
  57. data/lib/compiler/ast/class_def.fy +2 -1
  58. data/lib/compiler/ast/expression_list.fy +4 -5
  59. data/lib/compiler/ast/future_send.fy +1 -10
  60. data/lib/compiler/ast/goto.fy +46 -0
  61. data/lib/compiler/ast/identifier.fy +9 -7
  62. data/lib/compiler/ast/literals.fy +8 -1
  63. data/lib/compiler/ast/match.fy +14 -4
  64. data/lib/compiler/ast/message_send.fy +34 -6
  65. data/lib/compiler/ast/method_def.fy +6 -6
  66. data/lib/compiler/ast/node.fy +3 -3
  67. data/lib/compiler/ast/range.fy +1 -0
  68. data/lib/compiler/ast/script.fy +0 -2
  69. data/lib/compiler/ast/singleton_method_def.fy +2 -4
  70. data/lib/compiler/ast/string_interpolation.fy +17 -0
  71. data/lib/compiler/ast/super.fy +5 -4
  72. data/lib/compiler/ast/try_catch.fy +8 -6
  73. data/lib/compiler/ast/tuple_literal.fy +3 -2
  74. data/lib/compiler/command.fy +0 -1
  75. data/lib/compiler/compiler.fy +1 -5
  76. data/lib/compiler/stages.fy +6 -14
  77. data/lib/documentation.fy +57 -46
  78. data/lib/enumerable.fy +257 -23
  79. data/lib/enumerator.fy +122 -15
  80. data/lib/false_class.fy +10 -1
  81. data/lib/fancy_spec.fy +263 -61
  82. data/lib/fdoc.fy +11 -25
  83. data/lib/fiber.fy +11 -0
  84. data/lib/file.fy +8 -11
  85. data/lib/future.fy +84 -5
  86. data/lib/hash.fy +65 -14
  87. data/lib/integer.fy +35 -0
  88. data/lib/iteration.fy +54 -29
  89. data/lib/message.fy +6 -0
  90. data/lib/method.fy +0 -16
  91. data/lib/nil_class.fy +58 -8
  92. data/lib/number.fy +49 -22
  93. data/lib/object.fy +371 -65
  94. data/lib/package.fy +24 -1
  95. data/lib/package/installer.fy +5 -9
  96. data/lib/package/specification.fy +2 -2
  97. data/lib/parser/ext/lexer.lex +15 -11
  98. data/lib/parser/ext/parser.y +70 -23
  99. data/lib/parser/methods.fy +33 -14
  100. data/lib/proxy.fy +33 -3
  101. data/lib/range.fy +28 -0
  102. data/lib/rbx.fy +3 -1
  103. data/lib/rbx/actor.fy +53 -0
  104. data/lib/rbx/alpha.fy +31 -0
  105. data/lib/rbx/array.fy +21 -12
  106. data/lib/rbx/bignum.fy +6 -2
  107. data/lib/rbx/block.fy +23 -26
  108. data/lib/rbx/class.fy +54 -2
  109. data/lib/rbx/code_loader.fy +8 -4
  110. data/lib/rbx/date.fy +9 -0
  111. data/lib/rbx/directory.fy +18 -0
  112. data/lib/rbx/environment_variables.fy +1 -0
  113. data/lib/rbx/exception.fy +9 -2
  114. data/lib/rbx/fiber.fy +22 -4
  115. data/lib/rbx/file.fy +5 -5
  116. data/lib/rbx/fixnum.fy +5 -0
  117. data/lib/rbx/float.fy +11 -3
  118. data/lib/rbx/hash.fy +31 -16
  119. data/lib/rbx/integer.fy +1 -0
  120. data/lib/rbx/io.fy +17 -7
  121. data/lib/rbx/match_data.fy +15 -4
  122. data/lib/rbx/method.fy +40 -7
  123. data/lib/rbx/name_error.fy +4 -0
  124. data/lib/rbx/object.fy +92 -24
  125. data/lib/rbx/range.fy +20 -6
  126. data/lib/rbx/regexp.fy +11 -3
  127. data/lib/rbx/string.fy +51 -1
  128. data/lib/rbx/stringio.fy +17 -0
  129. data/lib/rbx/symbol.fy +15 -1
  130. data/lib/rbx/system.fy +20 -2
  131. data/lib/rbx/tcp_server.fy +4 -1
  132. data/lib/rbx/tcp_socket.fy +11 -0
  133. data/lib/rbx/time.fy +6 -0
  134. data/lib/rbx/tuple.fy +14 -5
  135. data/lib/set.fy +144 -29
  136. data/lib/stack.fy +42 -11
  137. data/lib/string.fy +118 -8
  138. data/lib/struct.fy +13 -3
  139. data/lib/symbol.fy +21 -2
  140. data/lib/thread_pool.fy +2 -1
  141. data/lib/true_class.fy +45 -7
  142. data/lib/tuple.fy +27 -9
  143. data/lib/version.fy +2 -2
  144. data/ruby_lib/fancy +43 -0
  145. data/ruby_lib/fdoc +23 -0
  146. data/ruby_lib/fspec +3 -0
  147. data/ruby_lib/fyi +3 -0
  148. data/ruby_lib/ifancy +3 -0
  149. data/tests/argv.fy +5 -9
  150. data/tests/array.fy +323 -196
  151. data/tests/assignment.fy +29 -29
  152. data/tests/block.fy +72 -59
  153. data/tests/class.fy +227 -138
  154. data/tests/control_flow.fy +83 -51
  155. data/tests/documentation.fy +8 -8
  156. data/tests/enumerable.fy +8 -0
  157. data/tests/enumerator.fy +47 -29
  158. data/tests/exception.fy +49 -32
  159. data/tests/file.fy +28 -28
  160. data/tests/fixnum.fy +170 -0
  161. data/tests/future.fy +24 -7
  162. data/tests/hash.fy +55 -38
  163. data/tests/method.fy +50 -43
  164. data/tests/nil_class.fy +37 -37
  165. data/tests/object.fy +152 -70
  166. data/tests/pattern_matching.fy +67 -31
  167. data/tests/range.fy +6 -6
  168. data/tests/set.fy +101 -4
  169. data/tests/stack.fy +14 -5
  170. data/tests/string.fy +115 -61
  171. data/tests/stringio.fy +18 -0
  172. data/tests/struct.fy +27 -0
  173. data/tests/symbol.fy +19 -6
  174. data/tests/true_class.fy +34 -34
  175. data/tests/tuple.fy +30 -12
  176. metadata +103 -81
  177. data/boot/rbx-compiler/compiler/ast/require.rb +0 -20
  178. data/examples/actor.fy +0 -37
  179. data/examples/curl_async.fy +0 -37
  180. data/lib/compiler/ast/require.fy +0 -15
  181. data/tests/number.fy +0 -135
  182. data/tests/parsing/sexp.fy +0 -50
@@ -0,0 +1,6 @@
1
+ class Fancy {
2
+ class Message {
3
+ read_slots: ('selector, 'arguments)
4
+ def initialize: @selector arguments: @arguments
5
+ }
6
+ }
@@ -3,20 +3,4 @@ class Method {
3
3
  An instance of Method represents a method on a Class.
4
4
  Every method in Fancy is an instance of the Method class.
5
5
  """
6
-
7
- def tests {
8
- """
9
- Returns an Array of all the FancySpec SpecTests defined for a
10
- Method.
11
- """
12
-
13
- @tests if_nil: { @tests = [] }
14
- @tests
15
- }
16
-
17
- def test: test_block {
18
- it = FancySpec new: self
19
- test_block call: [it]
20
- tests << it
21
- }
22
6
  }
@@ -1,52 +1,102 @@
1
1
  class NilClass {
2
- "NilClass. The class of the singleton @nil value."
2
+ """
3
+ NilClass. The class of the singleton @nil value.
4
+ """
3
5
 
4
6
  def NilClass new {
7
+ """
8
+ @return @nil.
9
+ """
10
+
5
11
  # always return nil singleton object when trying to create a new
6
12
  # NilClass instance
7
13
  nil
8
14
  }
9
15
 
10
16
  def if_true: block {
11
- "Returns @nil."
17
+ """
18
+ @return @nil.
19
+ """
20
+
12
21
  nil
13
22
  }
14
23
 
15
24
  def if_true: then_block else: else_block {
16
- "Calls @else_block."
25
+ """
26
+ @return Value of calling @else_block.
27
+
28
+ Calls @else_block.
29
+ """
17
30
  else_block call
18
31
  }
19
32
 
20
33
  def if_nil: block {
34
+ """
35
+ @block @Block@ to be called.
36
+ @return Value of calling @block with @self.
37
+
38
+ Calls @block with @self.
39
+ """
40
+
21
41
  block call: [self]
22
42
  }
23
43
 
24
44
  def if_nil: then_block else: else_block {
45
+ """
46
+ @then_block @Block@ to be called with @self.
47
+ @else_block Gets ignored.
48
+ @return Value of calling @then_block with @self.
49
+
50
+ Calls @then_block with @self.
51
+ """
52
+
25
53
  then_block call: [self]
26
54
  }
27
55
 
28
56
  def nil? {
29
- "Returns @true."
57
+ """
58
+ @return @true.
59
+ """
60
+
30
61
  true
31
62
  }
32
63
 
33
64
  def to_s {
34
- "Returns an empty @String@."
65
+ """
66
+ @return An empty @String@.
67
+ """
68
+
35
69
  ""
36
70
  }
37
71
 
72
+ alias_method: 'inspect for: 'to_s
73
+
38
74
  def to_a {
39
- "Returns an empty @Array@."
75
+ """
76
+ @return An empty @Array@.
77
+ """
78
+
40
79
  []
41
80
  }
42
81
 
43
82
  def not {
44
- "Returns @true."
83
+ """
84
+ @return @true.
85
+ """
86
+
45
87
  true
46
88
  }
47
89
 
48
90
  def inspect {
49
- "Returns @nil as a @String@."
91
+ """
92
+ @return @nil as a @String@.
93
+ """
94
+
50
95
  "nil"
51
96
  }
52
97
  }
98
+
99
+ nil documentation: """
100
+ @nil is the singleton nil value (only instance of @NilClass@).
101
+ NilClass##new yields @nil.
102
+ """
@@ -76,19 +76,31 @@ class Number {
76
76
  }
77
77
 
78
78
  def squared {
79
- "Returns the square of a Number."
79
+ """
80
+ @return Squared value of @self.
81
+
82
+ Returns the square of a Number.
83
+ """
80
84
 
81
85
  self * self
82
86
  }
83
87
 
84
88
  def doubled {
85
- "Returns the double value of a Number."
89
+ """
90
+ @return Doubled value of @self.
91
+
92
+ Returns the double value of a Number.
93
+ """
86
94
 
87
95
  self + self
88
96
  }
89
97
 
90
98
  def abs {
91
- "Returns the absolute (positive) value of a Number."
99
+ """
100
+ @return Absolute (positive) value of @self.
101
+
102
+ Returns the absolute (positive) value of a Number.
103
+ """
92
104
 
93
105
  if: (self < 0) then: {
94
106
  self * -1
@@ -98,41 +110,56 @@ class Number {
98
110
  }
99
111
 
100
112
  def negate {
101
- "Negates a Number (-1 becomes 1 and vice versa)."
113
+ """
114
+ @return Negated value of @self.
115
+
116
+ Negates a Number (-1 becomes 1 and vice versa).
117
+ """
102
118
 
103
119
  self * -1
104
120
  }
105
121
 
106
122
  def even? {
107
- "Indicates, if a Number is even."
123
+ """
124
+ @return @true, if @self is even, @false otherwise.
125
+
126
+ Indicates, if a Number is even.
127
+ """
108
128
 
109
129
  modulo: 2 . == 0
110
130
  }
111
131
 
112
132
  def odd? {
113
- "Indicates, if a Number is odd."
133
+ """
134
+ @return @true, if @self is odd, @false otherwise.
114
135
 
115
- self even? not
116
- }
136
+ Indicates, if a Number is odd.
137
+ """
117
138
 
118
- def to_num {
119
- self
139
+ self even? not
120
140
  }
121
- }
122
141
 
123
- class FancyEnumerable {
124
- def sum {
125
- """Calculates the sum of all the elements in the @Enumerable
126
- (assuming them to be @Number@s (implementing '+' & '*'))."""
142
+ def max: other {
143
+ """
144
+ @return Maximum value of @self and @other.
145
+ """
127
146
 
128
- reduce: |x y| { x + y } init_val: 0
147
+ if: (self < other) then: {
148
+ other
149
+ } else: {
150
+ self
151
+ }
129
152
  }
130
153
 
131
- def product {
132
- """Calculates the product of all the elements in the @Enumerable
133
- (assuming them to be @Number@s (implementing @+ & @*))."""
154
+ def min: other {
155
+ """
156
+ @return Minimum value of @self and @other.
157
+ """
134
158
 
135
- reduce: |x y| { x * y } init_val: 1
159
+ if: (self < other) then: {
160
+ self
161
+ } else: {
162
+ other
163
+ }
136
164
  }
137
- }
138
-
165
+ }
@@ -12,140 +12,205 @@ class Object {
12
12
  Returns the @String concatenation of @self and @other.
13
13
  Calls to_s on @self and @other and concatenates the results to a new @String.
14
14
  """
15
+
15
16
  to_s + (other to_s)
16
17
  }
17
18
 
18
19
  def loop: block {
19
- "Infinitely calls the block (loops)."
20
- block loop
20
+ """
21
+ @block @Block@ to be called endlessly (loop).
22
+
23
+ Infinitely calls the block (loops).
24
+ """
25
+
26
+ { true } while_true: block
21
27
  }
22
28
 
23
29
  def println {
24
- "Same as Console println: self. Prints the object on STDOUT, followed by a newline."
30
+ """
31
+ Same as:
32
+ Console println: self
33
+
34
+ Prints @self on @STDOUT, followed by a newline.
35
+ """
36
+
25
37
  Console println: to_s
26
38
  }
27
39
 
28
40
  def print {
29
- "Same as Console print: self. Prints the object on STDOUT."
41
+ """
42
+ Same as:
43
+ Console print: self
44
+
45
+ Prints @self on STDOUT.
46
+ """
47
+
30
48
  Console print: to_s
31
49
  }
32
50
 
33
51
  def != other {
34
- "Indicates, if two objects are unequal."
52
+ """
53
+ @other Other object to compare against.
54
+ @return @true if @self is not equal to @other, @false otherwise.
55
+
56
+ Indicates, if two objects are not equal.
57
+ """
58
+
35
59
  self == other not
36
60
  }
37
61
 
38
62
  def if_true: block {
39
- "Calls the @block if @true? returns @true"
63
+ """
64
+ @block @Block@ to be called.
65
+ @return Value of calling @block with @self.
66
+
67
+ Calls the @block (default behaviour).
68
+ """
69
+
40
70
  block call: [self]
41
71
  }
42
72
 
43
73
  def if_true: then_block else: else_block {
44
- "Calls the @then_block if @true? returns @true - otherwise @else_block is called"
74
+ """
75
+ @then_block @Block@ to be called.
76
+ @else_block Does not get called (default behaviour).
77
+
78
+ @return Value of calling @then_block with @self.
79
+
80
+ Calls the @then_block (default behaviour).
81
+ """
82
+
45
83
  then_block call: [self]
46
84
  }
47
85
 
48
86
  def if_false: block {
49
- "Calls the @block if @false? returns @true@"
87
+ """
88
+ @return @nil
89
+
90
+ Does nothing (default behaviour).
91
+ """
50
92
  nil
51
93
  }
52
94
 
53
95
  def if_false: then_block else: else_block {
54
- "Calls the @then_block if @false? returns @true - otherwise @else_block is called"
55
- else_block call
56
- }
96
+ """
97
+ @then_block Does not get called (default behaviour).
98
+ @else_block @Block@ to be called.
99
+ @return Value of calling @else_block.
57
100
 
58
- def if_nil: block {
59
- "Calls the @block if @nil? returns @true@"
60
- nil
61
- }
101
+ Calls @else_block (default behaviour).
102
+ """
62
103
 
63
- def if_nil: then_block else: else_block {
64
- "Calls the @then_block if @nil? returns @true - otherwise @else_block is called"
65
104
  else_block call
66
105
  }
67
106
 
107
+ alias_method: 'if_nil: for: 'if_false:
108
+ alias_method: 'if_nil:else: for: 'if_false:else:
109
+
68
110
  def nil? {
69
- "Returns @false."
111
+ """
112
+ @return @false.
113
+ """
114
+
70
115
  false
71
116
  }
72
117
 
73
118
  def false? {
74
- "Returns @false."
75
- false
76
- }
119
+ """
120
+ @return @false.
121
+ """
77
122
 
78
- def true? {
79
- "Returns @false."
80
123
  false
81
124
  }
82
125
 
83
- def or_take: other {
84
- "Returns self if it's non-nil, otherwise returns the given object."
85
-
86
- if: nil? then: {
87
- other
88
- } else: {
89
- self
90
- }
91
- }
126
+ def true? {
127
+ """
128
+ @return @false.
129
+ """
92
130
 
93
- def to_num {
94
- 0
131
+ false
95
132
  }
96
133
 
97
134
  def to_a {
135
+ """
136
+ @return @Array@ representation of @self.
137
+ """
138
+
98
139
  [self]
99
140
  }
100
141
 
101
142
  def to_i {
143
+ """
144
+ @return @Fixnum@ representation of @self.
145
+ """
146
+
102
147
  0
103
148
  }
104
149
 
105
150
  def to_enum {
151
+ """
152
+ @return @FancyEnumerator@ for @self using 'each: for iteration.
153
+ """
154
+
106
155
  FancyEnumerator new: self
107
156
  }
108
157
 
109
158
  def to_enum: iterator {
159
+ """
160
+ @iterator Message to use for iteration on @self.
161
+ @return @FancyEnumerator@ for @self using @iterator for iteration.
162
+ """
163
+
110
164
  FancyEnumerator new: self with: iterator
111
165
  }
112
166
 
113
167
  def and: other {
114
168
  """
169
+ @other Object or @Block@ (for short-circuit evaluation) to compare @self to.
170
+ @return @other if both @self and @other are true-ish, @self otherwise.
171
+
115
172
  Boolean conjunction.
116
- Returns @other if @self and @other are true-ish, otherwise @false.
173
+ If @self and @other are both true-ish (non-nil, non-false), returns @other.
174
+ If @other is a @Block@, calls it and returns its return value.
117
175
  """
118
176
 
119
177
  if_true: {
120
178
  { other = other call } if: (other is_a?: Block)
121
- return other
179
+ other
180
+ } else: {
181
+ self
122
182
  }
123
- return self
124
183
  }
125
184
 
126
185
  def or: other {
127
186
  """
187
+ @other Object or @Block@ (for short-circuit evaluation) to compare @self to.
188
+ @return @self if @self is true-ish, @other otherwise.
189
+
128
190
  Boolean disjunction.
129
- Returns true if either @self or other is true, otherwise nil.
191
+ If @self is true-ish (non-nil, non-false) returns @self.
192
+ Otherwise returns @other (if @other is a @Block@, calls it first and returns its return value)
130
193
  """
194
+
131
195
  if_true: {
132
- return self
196
+ self
133
197
  } else: {
134
198
  { other = other call } if: (other is_a?: Block)
135
- return other
199
+ other
136
200
  }
137
201
  }
138
202
 
139
- def or: other {
203
+ def xor: other {
140
204
  """
141
- Boolean disjunction.
142
- Returns true if either @self or other is true, otherwise nil.
205
+ @other @Object@ to compare @self against.
206
+ @return @true if only one of @self and @other is true, @false otherwise.
143
207
  """
144
- unless: self do: {
145
- { other = other call } if: (other is_a?: Block)
146
- return other
208
+
209
+ if_true: {
210
+ other not
211
+ } else: {
212
+ other not not
147
213
  }
148
- return self
149
214
  }
150
215
 
151
216
  alias_method: ':&& for: 'and:
@@ -156,6 +221,7 @@ class Object {
156
221
  Same as:
157
222
  cond if_true: block
158
223
  """
224
+
159
225
  cond if_true: block
160
226
  }
161
227
 
@@ -164,6 +230,7 @@ class Object {
164
230
  Same as:
165
231
  cond if_true: then_block else: else_block
166
232
  """
233
+
167
234
  cond if_true: then_block else: else_block
168
235
  }
169
236
 
@@ -185,6 +252,26 @@ class Object {
185
252
  cond_block until_do: body_block
186
253
  }
187
254
 
255
+ def do: body_block while: cond_block {
256
+ """
257
+ @body_block @Block@ to be called at least once and as long as @cond_block yields a true-ish value.
258
+ @cond_block Condition @Block@ used to determine if @body_block@ should be called again.
259
+ """
260
+
261
+ body_block call: [nil]
262
+ cond_block while_do: body_block
263
+ }
264
+
265
+ def do: body_block until: cond_block {
266
+ """
267
+ @body_block @Block@ to be called at least once and as long as @cond_block yields a false-ish value.
268
+ @cond_block Condition @Block@ used to determine if @body_block@ should be called again.
269
+ """
270
+
271
+ body_block call
272
+ cond_block until_do: body_block
273
+ }
274
+
188
275
  def unless: cond do: block {
189
276
  """
190
277
  Same as:
@@ -194,24 +281,51 @@ class Object {
194
281
  cond if_true: { nil } else: block
195
282
  }
196
283
 
284
+ def unless: cond do: block else: else_block {
285
+ """
286
+ Same as:
287
+ cond if_true: else_block else: block
288
+ """
289
+
290
+ cond if_true: else_block else: block
291
+ }
292
+
197
293
  def method: method_name {
198
- "Returns the method with a given name for self, if defined."
294
+ """
295
+ @return @Method@ with @method_name defined for @self, or @nil.
296
+ Returns the method with a given name for self, if defined.
297
+ """
199
298
 
200
299
  method(message_name: method_name)
201
300
  }
202
301
 
203
302
  def documentation {
204
- "Returns the documentation string for an Object."
205
- Fancy Documentation for: self . to_s
303
+ """
304
+ @return @Fancy::Documentation@ object for @self.
305
+
306
+ Returns the @Fancy::Documentation@ object for an Object.
307
+ """
308
+
309
+ Fancy Documentation for: self
206
310
  }
207
311
 
208
- def documentation: str {
209
- "Sets the documentation string for an Object."
210
- Fancy Documentation for: self is: str
312
+ def documentation: docstring {
313
+ """
314
+ @docstring New docstring for @self.
315
+
316
+ Sets the documentation string for an Object.
317
+ """
318
+
319
+ Fancy Documentation for: self is: docstring
211
320
  }
212
321
 
213
322
  def identity {
214
- "The identity method simply returns self."
323
+ """
324
+ @return @self.
325
+
326
+ The identity method simply returns self.
327
+ """
328
+
215
329
  self
216
330
  }
217
331
 
@@ -268,38 +382,230 @@ class Object {
268
382
  }
269
383
 
270
384
  def ? future {
385
+ """
386
+ @future Future object to get the value from.
387
+ @return Result of calling #value on @future.
388
+
389
+ Calls #value on @future. Shortcut method.
390
+ """
391
+
271
392
  future value
272
393
  }
273
394
 
274
395
  def yield {
396
+ """
397
+ Same as Fiber##yield.
398
+ """
399
+
275
400
  Fiber yield
276
401
  }
277
402
 
278
403
  def yield: values {
279
- Fiber yield: values
280
- }
404
+ """
405
+ Same as Fiber##yield:
406
+ """
281
407
 
282
- def wait: seconds {
283
- Fiber yield: [seconds]
408
+ Fiber yield: values
284
409
  }
285
410
 
286
411
  def next {
287
- "Skip to the next iteration"
412
+ """
413
+ Skip to the next iteration.
414
+ """
415
+
288
416
  Fancy NextIteration new raise!
289
417
  }
290
418
 
291
419
  def next: value {
292
- "Return value for this iteration and skip to the next one"
293
- (Fancy NextIteration new: value) raise!
420
+ """
421
+ @value Value for next iteration.
422
+
423
+ Returns @value for current iteration and skip to the next one.
424
+ """
425
+
426
+ Fancy NextIteration new: value . raise!
294
427
  }
295
428
 
296
429
  def break {
297
- "Stop iterating"
430
+ """
431
+ Breaks / Stops current iteration.
432
+ """
433
+
298
434
  Fancy BreakIteration new raise!
299
435
  }
300
436
 
301
437
  def break: value {
302
- "Return value from iteration"
303
- (Fancy BreakIteration new: value) raise!
438
+ """
439
+ @value Value to return from iteration.
440
+
441
+ Returns @value from iteratioen.
442
+ """
443
+
444
+ Fancy BreakIteration new: value . raise!
445
+ }
446
+
447
+ def __spawn_actor__ {
448
+ @__actor__active__ = true
449
+ Actor spawn: {
450
+ __actor__loop__
451
+ }
452
+ }
453
+
454
+ def __actor__loop__ {
455
+ while: { @__actor__active__ } do: {
456
+ sender = nil
457
+ try {
458
+ type, msg, sender = Actor receive
459
+ msg, params = msg
460
+ match type {
461
+ case 'async ->
462
+ self receive_message: msg with_params: params
463
+ case 'future ->
464
+ val = self receive_message: msg with_params: params
465
+ sender completed: val
466
+ }
467
+ } catch Exception => e {
468
+ { sender failed: e } if: sender
469
+ die!
470
+ e raise!
471
+ }
472
+ }
473
+ }
474
+
475
+ def __actor__die!__ {
476
+ @__actor__active__ = false
477
+ @__actor__ = nil
478
+ }
479
+
480
+ def __actor__ {
481
+ @__actor__ = @__actor__ || { __spawn_actor__ }
482
+ @__actor__
483
+ }
484
+
485
+ protected: [ '__spawn_actor__, '__actor__loop__, '__actor__die!__, '__actor__ ]
486
+
487
+ def die! {
488
+ """
489
+ Tells an object to let its actor to die (quit running).
490
+ """
491
+
492
+ __actor__die!__
493
+ }
494
+
495
+ def actor {
496
+ """
497
+ Returns the Object's actor.
498
+ If none exists at this moment, a new one will be created
499
+ and starts running in the background.
500
+ """
501
+
502
+ __actor__
503
+ }
504
+
505
+ def send_future: message with_params: params ([]) {
506
+ """
507
+ @message Message to be sent as a @FutureSend@.
508
+ @params @Array@ of parameters of the @FutureSend@.
509
+ @return @FutureSend@ object that will hold the return value of @message with @params on @self.
510
+
511
+ Creates a @FutureSend@ object (a Future / Promise) that will hold the value of sending @message to @self.
512
+ """
513
+
514
+ FutureSend new: __actor__ receiver: self message: message with_params: params
515
+ }
516
+
517
+ def send_async: message with_params: params ([]) {
518
+ """
519
+ @message Message to be sent asynchronously to @self.
520
+ @params @Array@ of parameters as part of sending @message asynchronously to @self.
521
+ @return @nil
522
+
523
+ Sends @message with @params to @self asynchronously and immediately returns @nil.
524
+ """
525
+
526
+ __actor__ ! ('async, (message, params), nil)
527
+ nil
528
+ }
529
+
530
+ def synchronized: block {
531
+ """
532
+ @block @Block@ to be run only by one Thread at a time.
533
+
534
+ Runs a given @Block@ in a synchronized fashion if called by multiple Threads.
535
+ Uses a @Mutex@ in the background for synchronization (created on demand for each @Object@).
536
+ """
537
+
538
+ @__mutex__ = @__mutex__ || { Mutex new() }
539
+ @__mutex__ synchronize(&block)
540
+ }
541
+
542
+ def copy_slots: slots from: object {
543
+ slots each: |s| {
544
+ set_slot: s value: (object get_slot: s)
545
+ }
546
+ }
547
+
548
+ def get_slots: slots {
549
+ """
550
+ @slots @Array@ of slot names to retrieve from @self.
551
+ @return @Array@ of slot values of slot names passed in via @slots.
552
+ """
553
+
554
+ slots map: |s| {
555
+ get_slot: s
556
+ }
557
+ }
558
+
559
+ def <=> other {
560
+ """
561
+ @other Other object to compare against.
562
+ @return -1 if @self is smaller, 0 if @self is equal or 1 if @self is greater or equal compared to @other.
563
+ """
564
+
565
+ { return -1 } if: (self < other)
566
+ { return 0 } if: (self == other)
567
+ return 1 # greater or equal to other
568
+ }
569
+
570
+ def do: block {
571
+ """
572
+ @block @Block@ to be called in the context of @self.
573
+
574
+ Helper method that calls @block with @self as the receiver.
575
+ This allows message cascading like code, e.g.:
576
+
577
+ some_complex_object do: {
578
+ method_1: arg1
579
+ method_2: arg2
580
+ method_3: arg3
581
+ }
582
+
583
+ # this is the same as:
584
+ some_complex_object method_1: arg1
585
+ some_complex_object method_2: arg2
586
+ some_complex_object method_3: arg3
587
+ """
588
+
589
+ block call_with_receiver: self
590
+ }
591
+
592
+ def slots {
593
+ """
594
+ @return @Set@ of slot names that @self has.
595
+ """
596
+
597
+ Set new: $ instance_variables map: |s| {
598
+ s rest to_sym
599
+ }
600
+ }
601
+
602
+ def sleep: seconds {
603
+ """
604
+ @seconds Amount of seconds to sleep.
605
+
606
+ Sets the current Thread (in which self is running) for a given amount to sleep.
607
+ """
608
+
609
+ Thread sleep: seconds
304
610
  }
305
- }
611
+ }