fancy 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }