fancy 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README.md +4 -1
- data/Rakefile +0 -52
- data/bin/fspec +22 -12
- data/bin/ifancy +1 -1
- data/boot/fancy_ext/class.rb +1 -0
- data/boot/fancy_ext/object.rb +8 -6
- data/boot/rbx-compiler/compiler/ast/method_def.rb +2 -0
- data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/parser.y +9 -0
- data/doc/api/fancy.jsonp +1 -1
- data/examples/stupid_quicksort.fy +11 -9
- data/lib/array.fy +26 -58
- data/lib/block.fy +0 -1
- data/lib/boot.fy +2 -2
- data/lib/class.fy +85 -0
- data/lib/compiler/ast/class_def.fy +1 -1
- data/lib/compiler/ast/expression_list.fy +4 -12
- data/lib/compiler/ast/identifier.fy +3 -3
- data/lib/compiler/ast/method_def.fy +3 -1
- data/lib/compiler/ast/singleton_method_def.fy +4 -1
- data/lib/contracts.fy +53 -56
- data/lib/dynamic_slot_object.fy +39 -3
- data/lib/enumerable.fy +144 -47
- data/lib/fancy_spec.fy +2 -6
- data/lib/file.fy +67 -0
- data/lib/future.fy +42 -3
- data/lib/hash.fy +35 -29
- data/lib/html.fy +1 -1
- data/lib/integer.fy +34 -0
- data/lib/main.fy +13 -7
- data/lib/message_sink.fy +1 -1
- data/lib/number.fy +10 -0
- data/lib/object.fy +27 -1
- data/lib/package.fy +2 -0
- data/lib/package/handler.fy +56 -0
- data/lib/package/installer.fy +21 -51
- data/lib/package/specification.fy +12 -5
- data/lib/package/uninstaller.fy +22 -3
- data/lib/parser/ext/parser.y +9 -0
- data/lib/proxy.fy +25 -2
- data/lib/rbx.fy +2 -1
- data/lib/rbx/array.fy +16 -1
- data/lib/rbx/class.fy +34 -9
- data/lib/rbx/file.fy +2 -2
- data/lib/rbx/fixnum.fy +1 -11
- data/lib/rbx/io.fy +4 -0
- data/lib/rbx/module.fy +11 -0
- data/lib/rbx/object.fy +12 -12
- data/lib/rbx/proc.fy +7 -0
- data/lib/rbx/string.fy +5 -1
- data/lib/rbx/symbol.fy +9 -0
- data/lib/string.fy +1 -1
- data/lib/tuple.fy +37 -35
- data/lib/version.fy +6 -5
- data/tests/array.fy +14 -2
- data/tests/class.fy +79 -0
- data/tests/dynamic_key_hash.fy +16 -0
- data/tests/dynamic_slot_object.fy +28 -0
- data/tests/dynamic_value_array.fy +12 -0
- data/tests/enumerable.fy +46 -0
- data/tests/file.fy +38 -0
- data/tests/fixnum.fy +22 -0
- data/tests/future.fy +40 -0
- data/tests/hash.fy +8 -7
- data/tests/object.fy +31 -5
- data/tests/set.fy +1 -1
- data/tests/string.fy +18 -2
- data/tests/tuple.fy +7 -0
- data/tools/fancy-mode.el +10 -0
- metadata +9 -12
- data/examples/99bottles.fy +0 -5
- data/examples/conditions_exceptions.fy +0 -9
- data/examples/conditions_parsing.fy +0 -68
- data/examples/dynamic.fy +0 -8
- data/examples/greeter.fy +0 -9
- data/examples/parsing.fy +0 -1
- data/lib/rbx/process.fy +0 -13
- data/lib/remote_object.fy +0 -59
@@ -20,11 +20,7 @@ class Fancy AST {
|
|
20
20
|
def bytecode: g {
|
21
21
|
pos(g)
|
22
22
|
size = @expressions size
|
23
|
-
@expressions each:
|
24
|
-
size = size - 1
|
25
|
-
expr bytecode: g
|
26
|
-
{ g pop() } if: (size > 0)
|
27
|
-
}
|
23
|
+
@expressions each: @{ bytecode: g } in_between: { g pop() }
|
28
24
|
}
|
29
25
|
|
30
26
|
# This method is only used by Rubinius' compiler classes and
|
@@ -33,13 +29,9 @@ class Fancy AST {
|
|
33
29
|
[]
|
34
30
|
}
|
35
31
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
def shift_docstring {
|
40
|
-
if: ((@expressions first kind_of?(Rubinius AST StringLiteral)) && \
|
41
|
-
(@expressions size > 1)) then: {
|
42
|
-
@expressions shift()
|
32
|
+
def docstring {
|
33
|
+
if: (@expressions first kind_of?(Rubinius AST StringLiteral)) then: {
|
34
|
+
@expressions first
|
43
35
|
}
|
44
36
|
}
|
45
37
|
}
|
@@ -57,9 +57,9 @@ class Fancy AST {
|
|
57
57
|
def bytecode: g {
|
58
58
|
pos(g)
|
59
59
|
match @string {
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
case "true" -> g push_true()
|
61
|
+
case "false" -> g push_false()
|
62
|
+
case "nil" -> g push_nil()
|
63
63
|
case _ ->
|
64
64
|
if: (g state() scope() search_local(name)) then: {
|
65
65
|
Rubinius AST LocalVariableAccess new(@line, name) bytecode(g)
|
@@ -3,7 +3,7 @@ class Fancy AST {
|
|
3
3
|
def initialize: @line name: @name args: @arguments (MethodArgs new: @line) body: @body (ExpressionList new: @line) access: @access ('public) {
|
4
4
|
{ @body = ExpressionList new: @line } unless: @body
|
5
5
|
@name = @name method_name: nil
|
6
|
-
@docstring = @body
|
6
|
+
@docstring = @body docstring
|
7
7
|
generate_ivar_assignment
|
8
8
|
|
9
9
|
if: (@body empty?) then: {
|
@@ -71,6 +71,7 @@ class Fancy AST {
|
|
71
71
|
to: (Self new: @line) \
|
72
72
|
args: (MessageArgs new: @line args: [method_ident])
|
73
73
|
ms bytecode: g
|
74
|
+
g pop()
|
74
75
|
}
|
75
76
|
|
76
77
|
def define_method_missing: g {
|
@@ -79,6 +80,7 @@ class Fancy AST {
|
|
79
80
|
to: (Self new: @line) \
|
80
81
|
args: (MessageArgs new: @line)
|
81
82
|
ms bytecode: g
|
83
|
+
g pop()
|
82
84
|
}
|
83
85
|
}
|
84
86
|
|
@@ -16,6 +16,9 @@ class Fancy AST {
|
|
16
16
|
|
17
17
|
class SingletonMethodDefScope : Rubinius AST DefineSingletonScope {
|
18
18
|
def initialize: @line name: @name args: @arguments body: @body {
|
19
|
+
if: (@body empty?) then: {
|
20
|
+
@body unshift_expression: $ NilLiteral new: @line
|
21
|
+
}
|
19
22
|
}
|
20
23
|
|
21
24
|
define_method("bytecode") |g, recv| {
|
@@ -24,7 +27,7 @@ class Fancy AST {
|
|
24
27
|
|
25
28
|
def bytecode: g receiver: receiver {
|
26
29
|
pos(g)
|
27
|
-
docstring = @body
|
30
|
+
docstring = @body docstring
|
28
31
|
sup = Rubinius AST DefineSingletonScope instance_method('bytecode)
|
29
32
|
sup bind(self) call(g, receiver)
|
30
33
|
MethodDef set: g docstring: docstring line: @line argnames: $ @arguments names()
|
data/lib/contracts.fy
CHANGED
@@ -1,60 +1,57 @@
|
|
1
|
-
class
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
def initialize: @block
|
30
|
-
def if_fullfilled: block {
|
31
|
-
@block call: [self]
|
32
|
-
block call
|
33
|
-
}
|
34
|
-
def true: expr {
|
35
|
-
{ RequirementError new: "#{expr} not true" . raise! } unless: expr
|
36
|
-
}
|
37
|
-
def false: expr {
|
38
|
-
{ RequirementError new: "#{expr} not false" . raise! } if: expr
|
39
|
-
}
|
40
|
-
}
|
41
|
-
}
|
42
|
-
|
43
|
-
# # usage:
|
44
|
-
# class Fixnum {
|
45
|
-
# def / other {
|
46
|
-
# require: @{
|
47
|
-
# true: $ other is_a?: Fixnum
|
48
|
-
# true: $ other > 0
|
49
|
-
# # better:
|
50
|
-
# other class is: Fixnum
|
51
|
-
# other is > 0
|
52
|
-
#
|
53
|
-
# } body: {
|
54
|
-
# "foo" println
|
1
|
+
# class Class {
|
2
|
+
# class Contracts {
|
3
|
+
# class ConditionBuilder : Proxy {
|
4
|
+
# def initialize: block for: @method class: @class {
|
5
|
+
# @conditions = <[]>
|
6
|
+
# block call: [self]
|
7
|
+
# insert_validations
|
8
|
+
# }
|
9
|
+
|
10
|
+
# def unknown_message: m with_params: p {
|
11
|
+
# if: (p size > 0 ) then: {
|
12
|
+
# @conditions[m to_s[[0,-2]]]: $ p first
|
13
|
+
# }
|
14
|
+
# }
|
15
|
+
|
16
|
+
# def insert_validations {
|
17
|
+
# name = @method name()
|
18
|
+
# alias_name = "__#{name}__orig__"
|
19
|
+
# conditions = @conditions
|
20
|
+
|
21
|
+
# @class alias_method: alias_name for: name
|
22
|
+
# @class define_method: name with: |p| {
|
23
|
+
# conditions each: |attr block| {
|
24
|
+
# # TODO
|
25
|
+
# }
|
26
|
+
# receive_message: alias_name with_params: p
|
27
|
+
# }
|
28
|
+
# }
|
55
29
|
# }
|
56
30
|
# }
|
31
|
+
|
32
|
+
# def preconditions: block for: method {
|
33
|
+
# Contracts ConditionBuilder new: block for: method class: self
|
34
|
+
# }
|
35
|
+
|
36
|
+
# def postconditions: block for: method {
|
37
|
+
# Contracts ConditionBuilder new: block for: method class: self
|
38
|
+
# }
|
57
39
|
# }
|
58
40
|
|
59
|
-
#
|
60
|
-
|
41
|
+
# # example
|
42
|
+
|
43
|
+
# class Person {
|
44
|
+
# read_slots: ('name, 'age)
|
45
|
+
|
46
|
+
# preconditions: @{
|
47
|
+
# name: @{ blank? not }
|
48
|
+
# age: @{ > 0 }
|
49
|
+
# } for: $ def initialize: @name age: @age
|
50
|
+
# }
|
51
|
+
|
52
|
+
|
53
|
+
# p = Person new: "chris" age: 25
|
54
|
+
# p inspect println
|
55
|
+
|
56
|
+
|
57
|
+
nil
|
data/lib/dynamic_slot_object.fy
CHANGED
@@ -1,9 +1,21 @@
|
|
1
|
-
class DynamicSlotObject : BasicObject {
|
1
|
+
class DynamicSlotObject : Fancy BasicObject {
|
2
|
+
"""
|
3
|
+
Helper class to dynamically create @Object@s with slots defined by sending messages to it.
|
4
|
+
|
5
|
+
Example:
|
6
|
+
dso = DynamicSlotObject new
|
7
|
+
dso name: \"Chris\"
|
8
|
+
dso age: 25
|
9
|
+
dso country: \"Germany\"
|
10
|
+
dso object # => Object with slots 'name, 'age and 'country defined
|
11
|
+
"""
|
12
|
+
|
2
13
|
def initialize {
|
3
14
|
@object = Object new
|
4
15
|
}
|
5
16
|
|
6
17
|
def object {
|
18
|
+
@object metaclass read_write_slots: (@object slots)
|
7
19
|
@object
|
8
20
|
}
|
9
21
|
|
@@ -14,7 +26,18 @@ class DynamicSlotObject : BasicObject {
|
|
14
26
|
}
|
15
27
|
}
|
16
28
|
|
17
|
-
class DynamicKeyHash : BasicObject {
|
29
|
+
class DynamicKeyHash : Fancy BasicObject {
|
30
|
+
"""
|
31
|
+
Helper class to dynamically create @Hash@es with keys and values defined by sending messages to it.
|
32
|
+
|
33
|
+
Example:
|
34
|
+
dkh = DynamicKeyHash new
|
35
|
+
dkh name: \"Chris\"
|
36
|
+
dkh age: 25
|
37
|
+
dkh country: \"Germany\"
|
38
|
+
dkh hash # => <['name => \"Chris\", 'age => 25, 'country => \"Germany\"]>
|
39
|
+
"""
|
40
|
+
|
18
41
|
def initialize: @deep (false) {
|
19
42
|
@hash = <[]>
|
20
43
|
}
|
@@ -36,7 +59,20 @@ class DynamicKeyHash : BasicObject {
|
|
36
59
|
}
|
37
60
|
}
|
38
61
|
|
39
|
-
class DynamicValueArray : BasicObject {
|
62
|
+
class DynamicValueArray : Fancy BasicObject {
|
63
|
+
"""
|
64
|
+
Helper class to dynamically create @Array@s with values defined by sending messages to it.
|
65
|
+
|
66
|
+
Example:
|
67
|
+
dva = DynamicValueArray new
|
68
|
+
dva name: \"Chris\"
|
69
|
+
dva age: 25
|
70
|
+
dva country: \"Germany\"
|
71
|
+
dva something_else
|
72
|
+
|
73
|
+
dva array # => [['name, \"Chris\"], ['age, 25], ['country, \"Germany\"], 'something_else]
|
74
|
+
"""
|
75
|
+
|
40
76
|
def initialize {
|
41
77
|
@arr = []
|
42
78
|
}
|
data/lib/enumerable.fy
CHANGED
@@ -4,6 +4,24 @@ class Fancy {
|
|
4
4
|
Mixin-Class with useful methods for collections that implement an @each:@ method.
|
5
5
|
"""
|
6
6
|
|
7
|
+
def at: index {
|
8
|
+
"""
|
9
|
+
@index @Fixnum@ that is the 0-based index into @self.
|
10
|
+
@return Value in @self at 0-based position defined by @index.
|
11
|
+
|
12
|
+
Example:
|
13
|
+
\"foo\” at: 2 # => \"o\"
|
14
|
+
\"foo\” at: 3 # => nil
|
15
|
+
"""
|
16
|
+
|
17
|
+
i = 0
|
18
|
+
each: |x| {
|
19
|
+
{ return x } if: $ i == index
|
20
|
+
i = i + 1
|
21
|
+
}
|
22
|
+
return nil
|
23
|
+
}
|
24
|
+
|
7
25
|
def each_with_index: block {
|
8
26
|
"""
|
9
27
|
@block @Block@ to be called with each element and its index in the @self.
|
@@ -20,6 +38,48 @@ class Fancy {
|
|
20
38
|
}
|
21
39
|
}
|
22
40
|
|
41
|
+
def first {
|
42
|
+
"""
|
43
|
+
@return The first element in the @Fancy::Enumerable@.
|
44
|
+
"""
|
45
|
+
at: 0
|
46
|
+
}
|
47
|
+
|
48
|
+
def second {
|
49
|
+
"""
|
50
|
+
@return The second element in the @Fancy::Enumerable@.
|
51
|
+
"""
|
52
|
+
at: 1
|
53
|
+
}
|
54
|
+
|
55
|
+
def third {
|
56
|
+
"""
|
57
|
+
@return The third element in the @Fancy::Enumerable@.
|
58
|
+
"""
|
59
|
+
at: 2
|
60
|
+
}
|
61
|
+
|
62
|
+
def fourth {
|
63
|
+
"""
|
64
|
+
@return The fourth element in the @Fancy::Enumerable@.
|
65
|
+
"""
|
66
|
+
at: 3
|
67
|
+
}
|
68
|
+
|
69
|
+
def last {
|
70
|
+
"""
|
71
|
+
@return Last element in @self or @nil, if empty.
|
72
|
+
|
73
|
+
Returns the last element in a @Fancy::Enumerable@.
|
74
|
+
"""
|
75
|
+
|
76
|
+
item = nil
|
77
|
+
each: |x| {
|
78
|
+
item = x
|
79
|
+
}
|
80
|
+
item
|
81
|
+
}
|
82
|
+
|
23
83
|
def includes?: item {
|
24
84
|
"""
|
25
85
|
@item Item to check if it's included in @self.
|
@@ -28,7 +88,7 @@ class Fancy {
|
|
28
88
|
Indicates, if a collection includes a given element.
|
29
89
|
"""
|
30
90
|
|
31
|
-
any?: |x| {
|
91
|
+
any?: |x| { x == item }
|
32
92
|
}
|
33
93
|
|
34
94
|
def each: each_block in_between: between_block {
|
@@ -44,7 +104,7 @@ class Fancy {
|
|
44
104
|
}
|
45
105
|
}
|
46
106
|
|
47
|
-
def join: str {
|
107
|
+
def join: str ("") {
|
48
108
|
"""
|
49
109
|
@str Value (usually a @String@) to be used for the joined @String@.
|
50
110
|
@return @String@ containing all elements in @self interspersed with @str.
|
@@ -144,6 +204,38 @@ class Fancy {
|
|
144
204
|
coll
|
145
205
|
}
|
146
206
|
|
207
|
+
def map_with_index: block {
|
208
|
+
"""
|
209
|
+
@block A @Block@ that gets called with each element and its index in @self.
|
210
|
+
@return An @Array@ containing all values of calling @block with each element and its index in @self.
|
211
|
+
|
212
|
+
Returns a new @Array@ with the results of calling a given block for every element and its index.
|
213
|
+
"""
|
214
|
+
|
215
|
+
coll = []
|
216
|
+
each_with_index: |x i| {
|
217
|
+
coll << (block call: [x, i])
|
218
|
+
}
|
219
|
+
coll
|
220
|
+
}
|
221
|
+
|
222
|
+
def map_chained: blocks {
|
223
|
+
"""
|
224
|
+
@blocks Collection of @Block@s to be called sequentially for every element in @self.
|
225
|
+
@return Collection of all values in @self successively called with all blocks in @blocks.
|
226
|
+
|
227
|
+
Example:
|
228
|
+
(1,2,3) map_chained: (@{ + 1 }, 'to_s, @{ * 2 })
|
229
|
+
# => [\"22\", \"33\", \"44\"]
|
230
|
+
"""
|
231
|
+
|
232
|
+
map: |v| {
|
233
|
+
blocks inject: v into: |acc b| {
|
234
|
+
b call: [acc]
|
235
|
+
}
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
147
239
|
def select: condition {
|
148
240
|
"""
|
149
241
|
@condition A @Block@ that is used as a filter on all elements in @self.
|
@@ -285,23 +377,23 @@ class Fancy {
|
|
285
377
|
reduce: block init_val: val
|
286
378
|
}
|
287
379
|
|
288
|
-
def
|
380
|
+
def unique {
|
289
381
|
"""
|
290
382
|
@return @Array@ of all unique elements in @self.
|
291
383
|
|
292
384
|
Returns a new Array with all unique values (double entries are skipped).
|
293
385
|
|
294
386
|
Example:
|
295
|
-
[1,2,1,2,3]
|
387
|
+
[1,2,1,2,3] unique # => [1,2,3]
|
296
388
|
"""
|
297
389
|
|
298
|
-
|
390
|
+
unique_vals = []
|
299
391
|
each: |x| {
|
300
|
-
unless: (
|
301
|
-
|
392
|
+
unless: (unique_vals includes?: x) do: {
|
393
|
+
unique_vals << x
|
302
394
|
}
|
303
395
|
}
|
304
|
-
|
396
|
+
unique_vals
|
305
397
|
}
|
306
398
|
|
307
399
|
def size {
|
@@ -312,7 +404,7 @@ class Fancy {
|
|
312
404
|
"""
|
313
405
|
|
314
406
|
i = 0
|
315
|
-
each:
|
407
|
+
each: {
|
316
408
|
i = i + 1
|
317
409
|
}
|
318
410
|
i
|
@@ -328,31 +420,6 @@ class Fancy {
|
|
328
420
|
size == 0
|
329
421
|
}
|
330
422
|
|
331
|
-
def first {
|
332
|
-
"""
|
333
|
-
@return First element in @self or @nil, if empty.
|
334
|
-
"""
|
335
|
-
|
336
|
-
each: |x| {
|
337
|
-
return x
|
338
|
-
}
|
339
|
-
nil
|
340
|
-
}
|
341
|
-
|
342
|
-
def last {
|
343
|
-
"""
|
344
|
-
@return Last element in @self or @nil, if empty.
|
345
|
-
|
346
|
-
Returns the last element in an Enumerable.
|
347
|
-
"""
|
348
|
-
|
349
|
-
item = nil
|
350
|
-
each: |x| {
|
351
|
-
item = x
|
352
|
-
}
|
353
|
-
item
|
354
|
-
}
|
355
|
-
|
356
423
|
def compact {
|
357
424
|
"""
|
358
425
|
@return @Array@ with all non-nil elements in @self.
|
@@ -363,16 +430,16 @@ class Fancy {
|
|
363
430
|
[1,2,nil,3,nil] compact # => [1,2,3]
|
364
431
|
"""
|
365
432
|
|
366
|
-
reject:
|
433
|
+
reject: @{ nil? }
|
367
434
|
}
|
368
435
|
|
369
|
-
def superior_by: comparison_block taking: selection_block (
|
436
|
+
def superior_by: comparison_block taking: selection_block (@{ identity }) {
|
370
437
|
"""
|
371
438
|
@comparison_block @Block@ to be used for comparison.
|
372
|
-
@selection_block @Block@ to be used for selecting the values to be used for comparison by @
|
439
|
+
@selection_block @Block@ to be used for selecting the values to be used for comparison by @comparison_block.
|
373
440
|
@return Superior element in @self in terms of @comparison_block.
|
374
441
|
|
375
|
-
Returns the superior element in the @Enumerable that has met
|
442
|
+
Returns the superior element in the @Fancy::Enumerable@ that has met
|
376
443
|
the given comparison block with all other elements,
|
377
444
|
applied to whatever @selection_block returns for each element.
|
378
445
|
@selection_block defaults to @identity.
|
@@ -424,7 +491,7 @@ class Fancy {
|
|
424
491
|
(assuming them to be @Number@s (implementing '+' & '*')).
|
425
492
|
"""
|
426
493
|
|
427
|
-
|
494
|
+
inject: 0 into: '+
|
428
495
|
}
|
429
496
|
|
430
497
|
def product {
|
@@ -433,7 +500,7 @@ class Fancy {
|
|
433
500
|
(assuming them to be @Number@s (implementing @+ & @*)).
|
434
501
|
"""
|
435
502
|
|
436
|
-
|
503
|
+
inject: 1 into: '*
|
437
504
|
}
|
438
505
|
|
439
506
|
def average {
|
@@ -451,7 +518,7 @@ class Fancy {
|
|
451
518
|
@return @Array@ of @Array@s, partitioned by equal return values of calling @block with each element
|
452
519
|
|
453
520
|
Example:
|
454
|
-
0
|
521
|
+
(0..10) partition_by: @{ < 3 } # => [[0, 1, 2], [3, 4, 5, 6, 7, 8, 9, 10]]
|
455
522
|
"""
|
456
523
|
last = block call: [first]
|
457
524
|
coll = []
|
@@ -475,7 +542,7 @@ class Fancy {
|
|
475
542
|
@return Random element in @self.
|
476
543
|
"""
|
477
544
|
|
478
|
-
at:
|
545
|
+
at: $ size random
|
479
546
|
}
|
480
547
|
|
481
548
|
def sort_by: block {
|
@@ -534,8 +601,7 @@ class Fancy {
|
|
534
601
|
In either case, it simply converts @self to an @Array@ and returns it in reversed order.
|
535
602
|
"""
|
536
603
|
|
537
|
-
|
538
|
-
rev reverse
|
604
|
+
self to_a reverse
|
539
605
|
}
|
540
606
|
|
541
607
|
def to_hash: block {
|
@@ -548,12 +614,12 @@ class Fancy {
|
|
548
614
|
# => <[3 => \"foo\", 5 => \"hello\", 2 => \"ok\", 0 => \"\"]>
|
549
615
|
"""
|
550
616
|
|
551
|
-
|
552
|
-
|
617
|
+
|
618
|
+
inject: <[]> into: |h val| {
|
553
619
|
key = block call: [val]
|
554
620
|
h[key]: val
|
621
|
+
h
|
555
622
|
}
|
556
|
-
h
|
557
623
|
}
|
558
624
|
|
559
625
|
def reverse_each: block {
|
@@ -567,5 +633,36 @@ class Fancy {
|
|
567
633
|
|
568
634
|
reverse each: block
|
569
635
|
}
|
636
|
+
|
637
|
+
def count: block {
|
638
|
+
"""
|
639
|
+
@block Predicate @Block@ called with each element.
|
640
|
+
@return @Fixnum@ that is the amount of elements in @self for which @block yields @true.
|
641
|
+
|
642
|
+
Example:
|
643
|
+
(0..10) count: @{ even? } # => 6 (even numbers are: 0,2,4,6,8,10)
|
644
|
+
[1,2,3] count: @{ odd? } # => 2
|
645
|
+
[1,2, \"foo\"] count: @{ class == String } # => 1
|
646
|
+
"""
|
647
|
+
|
648
|
+
count = 0
|
649
|
+
each: |x| {
|
650
|
+
{ count = count + 1 } if: $ block call: [x]
|
651
|
+
}
|
652
|
+
count
|
653
|
+
}
|
654
|
+
|
655
|
+
def to_s {
|
656
|
+
"""
|
657
|
+
@return @String@ concatenation of elements in @self.
|
658
|
+
|
659
|
+
Example:
|
660
|
+
(1,2,3) to_s # => \"123\"
|
661
|
+
[1,2,3] to_s # => \"123\"
|
662
|
+
\"foo\" to_s # => \"foo\"
|
663
|
+
"""
|
664
|
+
|
665
|
+
join
|
666
|
+
}
|
570
667
|
}
|
571
668
|
}
|