fancy 0.6.0 → 0.7.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.
- 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
|
}
|