fancy 0.8.0 → 0.9.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 +5 -4
- data/bin/fspec +19 -1
- data/bin/ifancy +139 -35
- data/boot/README +2 -9
- data/boot/extconf.rb +0 -1
- data/boot/fancy_ext/module.rb +5 -15
- data/boot/fancy_ext/thread.rb +22 -9
- data/boot/rbx-compiler/README +0 -4
- data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/parser.y +1 -0
- data/doc/api/fancy.css +1 -6
- data/doc/api/fancy.jsonp +1 -1
- data/doc/api/fdoc.js +2 -4
- data/doc/api/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/doc/api/images/ui-bg_flat_0_eeeeee_40x100.png +0 -0
- data/doc/api/images/ui-bg_flat_55_ffffff_40x100.png +0 -0
- data/doc/api/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/doc/api/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/doc/api/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png +0 -0
- data/doc/api/images/ui-bg_highlight-soft_25_0073ea_1x100.png +0 -0
- data/doc/api/images/ui-bg_highlight-soft_50_dddddd_1x100.png +0 -0
- data/doc/api/images/ui-icons_0073ea_256x240.png +0 -0
- data/doc/api/images/ui-icons_454545_256x240.png +0 -0
- data/doc/api/images/ui-icons_666666_256x240.png +0 -0
- data/doc/api/images/ui-icons_ff0084_256x240.png +0 -0
- data/doc/api/images/ui-icons_ffffff_256x240.png +0 -0
- data/doc/api/index.html +5 -4
- data/doc/api/jquery-1.8.2.min.js +2 -0
- data/doc/api/jquery-ui-1.9.0.custom.min.css +5 -0
- data/doc/api/jquery-ui-1.9.0.custom.min.js +6 -0
- data/doc/features.md +8 -3
- data/examples/argv.fy +1 -1
- data/examples/closures.fy +1 -4
- data/examples/echo.fy +2 -2
- data/examples/guess_number.fy +18 -0
- data/examples/nested_classes.fy +3 -15
- data/lib/argv.fy +23 -18
- data/lib/array.fy +18 -37
- data/lib/block.fy +125 -0
- data/lib/boot.fy +1 -0
- data/lib/compiler/ast/block.fy +1 -1
- data/lib/compiler/ast/identifier.fy +1 -1
- data/lib/compiler/ast/message_send.fy +0 -13
- data/lib/compiler/ast/method_def.fy +1 -1
- data/lib/compiler/ast/singleton_method_def.fy +1 -0
- data/lib/compiler/ast/tuple_literal.fy +1 -1
- data/lib/compiler/command.fy +1 -1
- data/lib/compiler/compiler.fy +8 -6
- data/lib/contracts.fy +1 -1
- data/lib/directory.fy +1 -1
- data/lib/dynamic_slot_object.fy +1 -1
- data/lib/enumerable.fy +316 -25
- data/lib/enumerator.fy +11 -8
- data/lib/eval.fy +0 -3
- data/lib/fancy_spec.fy +27 -0
- data/lib/fdoc.fy +8 -8
- data/lib/file.fy +25 -1
- data/lib/hash.fy +91 -0
- data/lib/html.fy +40 -11
- data/lib/integer.fy +4 -0
- data/lib/main.fy +18 -11
- data/lib/object.fy +33 -7
- data/lib/option_parser.fy +20 -1
- data/lib/package/dependency.fy +8 -0
- data/lib/package/dependency_installer.fy +3 -6
- data/lib/package/handler.fy +4 -4
- data/lib/package/installer.fy +2 -5
- data/lib/package/list.fy +3 -4
- data/lib/parser/ext/parser.y +1 -0
- data/lib/proxies.fy +0 -2
- data/lib/queue.fy +7 -0
- data/lib/rbx.fy +1 -0
- data/lib/rbx/actor.fy +3 -1
- data/lib/rbx/alpha.fy +24 -0
- data/lib/rbx/array.fy +3 -1
- data/lib/rbx/class.fy +5 -8
- data/lib/rbx/date_time.fy +14 -0
- data/lib/rbx/file.fy +6 -0
- data/lib/rbx/hash.fy +42 -0
- data/lib/rbx/thread.fy +5 -7
- data/lib/string.fy +56 -4
- data/lib/symbol.fy +29 -1
- data/lib/time.fy +17 -0
- data/lib/vars.fy +4 -3
- data/lib/version.fy +1 -1
- data/ruby_lib/interactive/hilight.rb +125 -0
- data/tests/array.fy +19 -7
- data/tests/block.fy +103 -4
- data/tests/class.fy +31 -26
- data/tests/control_flow.fy +0 -1
- data/tests/dynamic_key_hash.fy +22 -1
- data/tests/enumerable.fy +239 -7
- data/tests/enumerator.fy +7 -0
- data/tests/file.fy +16 -0
- data/tests/future.fy +1 -11
- data/tests/future_proxy.fy +8 -0
- data/tests/hash.fy +132 -9
- data/tests/html.fy +30 -13
- data/tests/integer.fy +3 -0
- data/tests/method.fy +6 -11
- data/tests/object.fy +12 -5
- data/tests/option_parser.fy +12 -3
- data/tests/string.fy +69 -1
- data/tests/symbol.fy +24 -0
- metadata +42 -12
- data/boot/rsexp_pretty_printer.rb +0 -76
- data/doc/api/jquery-ui.min.js +0 -401
- data/doc/api/jquery.tools.min.js +0 -192
- data/doc/api/themeswitchertool.js +0 -250
- data/examples/future_sends.fy +0 -15
data/lib/boot.fy
CHANGED
data/lib/compiler/ast/block.fy
CHANGED
@@ -42,19 +42,6 @@ class Fancy AST {
|
|
42
42
|
return nil
|
43
43
|
}
|
44
44
|
|
45
|
-
# check if we might have a block invocation using block(x,y) syntax.
|
46
|
-
if: ruby_send? then: {
|
47
|
-
if: (@receiver is_a?: Self) then: {
|
48
|
-
if: (g state() scope() search_local(@name name)) then: {
|
49
|
-
@name bytecode: g
|
50
|
-
args = ArrayLiteral new: @line array: (@args args)
|
51
|
-
args bytecode: g
|
52
|
-
g send('call:, 1, false)
|
53
|
-
return nil
|
54
|
-
}
|
55
|
-
}
|
56
|
-
}
|
57
|
-
|
58
45
|
@receiver bytecode: g
|
59
46
|
@args bytecode: g
|
60
47
|
pos(g)
|
@@ -13,6 +13,7 @@ class Fancy AST {
|
|
13
13
|
|
14
14
|
class SingletonMethodDefScope : Rubinius AST DefineSingletonScope {
|
15
15
|
def initialize: @line name: @name args: @arguments body: @body {
|
16
|
+
{ @body = ExpressionList new: @line } unless: @body
|
16
17
|
if: (@body empty?) then: {
|
17
18
|
@body unshift_expression: $ NilLiteral new: @line
|
18
19
|
}
|
data/lib/compiler/command.fy
CHANGED
data/lib/compiler/compiler.fy
CHANGED
@@ -3,12 +3,12 @@ class Fancy {
|
|
3
3
|
read_write_slots: [ 'parser, 'generator, 'packager, 'writer ]
|
4
4
|
|
5
5
|
def self compiled_name: file {
|
6
|
-
|
7
|
-
|
6
|
+
"""
|
7
|
+
Returns a the compiled filename for @file
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
If file ends with .fy extention the will return with .fyc extension
|
10
|
+
Otherwise it will append .compiled.fyc to the filename.
|
11
|
+
"""
|
12
12
|
|
13
13
|
if: (file suffix?(".fy")) then: {
|
14
14
|
file + "c"
|
@@ -18,7 +18,9 @@ class Fancy {
|
|
18
18
|
}
|
19
19
|
|
20
20
|
def self from: first_stage to: last_stage {
|
21
|
-
"
|
21
|
+
"""
|
22
|
+
Creates a new compiler from @first_stage to @last_stage.
|
23
|
+
"""
|
22
24
|
|
23
25
|
new(first_stage, last_stage)
|
24
26
|
}
|
data/lib/contracts.fy
CHANGED
@@ -57,7 +57,7 @@ class Class {
|
|
57
57
|
"""
|
58
58
|
|
59
59
|
pim = Set new: $ provided_interface_methods map: @{ message_name to_s } + instance_methods
|
60
|
-
methods all?: |m| { pim includes?: (m message_name to_s) }
|
60
|
+
methods to_a all?: |m| { pim includes?: (m message_name to_s) }
|
61
61
|
}
|
62
62
|
|
63
63
|
def missing_methods_for_interface: methods {
|
data/lib/directory.fy
CHANGED
data/lib/dynamic_slot_object.fy
CHANGED
data/lib/enumerable.fy
CHANGED
@@ -42,6 +42,7 @@ class Fancy {
|
|
42
42
|
"""
|
43
43
|
@return The first element in the @Fancy::Enumerable@.
|
44
44
|
"""
|
45
|
+
|
45
46
|
at: 0
|
46
47
|
}
|
47
48
|
|
@@ -49,6 +50,7 @@ class Fancy {
|
|
49
50
|
"""
|
50
51
|
@return The second element in the @Fancy::Enumerable@.
|
51
52
|
"""
|
53
|
+
|
52
54
|
at: 1
|
53
55
|
}
|
54
56
|
|
@@ -56,6 +58,7 @@ class Fancy {
|
|
56
58
|
"""
|
57
59
|
@return The third element in the @Fancy::Enumerable@.
|
58
60
|
"""
|
61
|
+
|
59
62
|
at: 2
|
60
63
|
}
|
61
64
|
|
@@ -63,6 +66,7 @@ class Fancy {
|
|
63
66
|
"""
|
64
67
|
@return The fourth element in the @Fancy::Enumerable@.
|
65
68
|
"""
|
69
|
+
|
66
70
|
at: 3
|
67
71
|
}
|
68
72
|
|
@@ -136,6 +140,15 @@ class Fancy {
|
|
136
140
|
"""
|
137
141
|
Similar to @each:@ but calls an additional @Block@ between
|
138
142
|
calling the first @Block@ for each element in self.
|
143
|
+
|
144
|
+
Example:
|
145
|
+
result = \"\"
|
146
|
+
[1,2,3,4,5] each: |i| {
|
147
|
+
result << i
|
148
|
+
} in_between: {
|
149
|
+
result << \"-\"
|
150
|
+
}
|
151
|
+
result # => \"1-2-3-4-5\"
|
139
152
|
"""
|
140
153
|
|
141
154
|
between = { between = between_block }
|
@@ -152,6 +165,7 @@ class Fancy {
|
|
152
165
|
|
153
166
|
Joins a collection with a @String@ between each element, returning a new @String@.
|
154
167
|
|
168
|
+
Example:
|
155
169
|
\"hello, world\" join: \"-\" # => \"h-e-l-l-o-,- -w-o-r-l-d\"
|
156
170
|
"""
|
157
171
|
|
@@ -172,7 +186,7 @@ class Fancy {
|
|
172
186
|
Works similar to @Fancy::Enumerable#inject:into:@ but uses first element as value injected.
|
173
187
|
|
174
188
|
Example:
|
175
|
-
(1,2,3)
|
189
|
+
(1,2,3) join_by: '+ # => same as: (2,3) inject: 1 into: '+
|
176
190
|
"""
|
177
191
|
|
178
192
|
first, *rest = self
|
@@ -232,6 +246,79 @@ class Fancy {
|
|
232
246
|
}
|
233
247
|
}
|
234
248
|
|
249
|
+
def find: item do: block {
|
250
|
+
"""
|
251
|
+
@item Item to find in @self.
|
252
|
+
@block @Block@ to be called with @item if found in @self.
|
253
|
+
|
254
|
+
Calls @block with @item, if found.
|
255
|
+
If @item is not in @self, @block is not called.
|
256
|
+
"""
|
257
|
+
|
258
|
+
if: (find: item) then: block
|
259
|
+
}
|
260
|
+
|
261
|
+
def find_with_index: item do: block {
|
262
|
+
"""
|
263
|
+
@item Item to find in @self.
|
264
|
+
@block @Block@ to be called with @item and its index in @self.
|
265
|
+
|
266
|
+
Calls @block with @item and its index in @self, if found.
|
267
|
+
If @item is not in @self, @block is not called.
|
268
|
+
"""
|
269
|
+
|
270
|
+
for_every: item with_index_do: |x i| {
|
271
|
+
return block call: [x, i]
|
272
|
+
}
|
273
|
+
nil
|
274
|
+
}
|
275
|
+
|
276
|
+
def for_every: item with_index_do: block {
|
277
|
+
"""
|
278
|
+
@item Item to call @block with.
|
279
|
+
@block @Block@ to be called with @item and each of its indexes in @self.
|
280
|
+
|
281
|
+
Calls @block with @item and each of its indexes in @self, if @item is in @self.
|
282
|
+
"""
|
283
|
+
|
284
|
+
each_with_index: |x i| {
|
285
|
+
if: (item == x) then: {
|
286
|
+
block call: [x, i]
|
287
|
+
}
|
288
|
+
}
|
289
|
+
}
|
290
|
+
|
291
|
+
def for_every: item do: block {
|
292
|
+
"""
|
293
|
+
@item Item to call @block with.
|
294
|
+
@block @Block@ to be called with @item for every occurance of @item in @self.
|
295
|
+
|
296
|
+
Calls @block with @item for each occurance of @item in @self.
|
297
|
+
|
298
|
+
Example:
|
299
|
+
count = 0
|
300
|
+
[1,2,3,2,1] for_every: 1 do: { count = count + 1 }
|
301
|
+
# count is now 2
|
302
|
+
"""
|
303
|
+
|
304
|
+
each: |x| {
|
305
|
+
if: (item == x) then: { block call: [x] }
|
306
|
+
}
|
307
|
+
}
|
308
|
+
|
309
|
+
def last_index_of: item {
|
310
|
+
"""
|
311
|
+
@item Item for which the last index in @self should be found.
|
312
|
+
@return Last index of @item in @self, or @nil (if not in @self).
|
313
|
+
|
314
|
+
Returns the last index for @item in @self, or @nil, if @item is not in @self.
|
315
|
+
"""
|
316
|
+
|
317
|
+
last_idx = nil
|
318
|
+
for_every: item with_index_do: |_ i| { last_idx = i }
|
319
|
+
last_idx
|
320
|
+
}
|
321
|
+
|
235
322
|
def find_by: block {
|
236
323
|
"""
|
237
324
|
Similar to @find:@ but takes a block that is called for each element to find it.
|
@@ -292,6 +379,14 @@ class Fancy {
|
|
292
379
|
}
|
293
380
|
}
|
294
381
|
|
382
|
+
def flat_map: block {
|
383
|
+
"""
|
384
|
+
Similar to @Fancy::Enumerable#map:@ but returns the result @Array@ flattened.
|
385
|
+
"""
|
386
|
+
|
387
|
+
map: block . tap: @{ flatten! }
|
388
|
+
}
|
389
|
+
|
295
390
|
def select: condition {
|
296
391
|
"""
|
297
392
|
@condition A @Block@ that is used as a filter on all elements in @self.
|
@@ -307,6 +402,24 @@ class Fancy {
|
|
307
402
|
coll
|
308
403
|
}
|
309
404
|
|
405
|
+
def select_with_index: condition {
|
406
|
+
"""
|
407
|
+
@condition A @Block@ that is used as a filter on all elements in @self.
|
408
|
+
@return An @Array@ containing all elements and their indices in @self that yield @true when called with @condition.
|
409
|
+
|
410
|
+
Returns a new @Array@ with all elements and their indices that meet the given
|
411
|
+
condition block. @condition is called with each element and its index in @self.
|
412
|
+
"""
|
413
|
+
|
414
|
+
tmp = []
|
415
|
+
each_with_index: |obj idx| {
|
416
|
+
if: (condition call: [obj, idx]) then: {
|
417
|
+
tmp << [obj, idx]
|
418
|
+
}
|
419
|
+
}
|
420
|
+
tmp
|
421
|
+
}
|
422
|
+
|
310
423
|
def reject: condition {
|
311
424
|
"""
|
312
425
|
Similar to @select:@ but inverse.
|
@@ -354,14 +467,14 @@ class Fancy {
|
|
354
467
|
"""
|
355
468
|
|
356
469
|
coll = []
|
357
|
-
drop =
|
358
|
-
first_check = true
|
470
|
+
drop? = false
|
471
|
+
first_check? = true
|
359
472
|
each: |x| {
|
360
|
-
if: (drop or: first_check) then: {
|
361
|
-
drop = condition call: [x]
|
362
|
-
first_check =
|
473
|
+
if: (drop? or: first_check?) then: {
|
474
|
+
drop? = condition call: [x]
|
475
|
+
first_check? = false
|
363
476
|
# check, if we actually have to insert this one:
|
364
|
-
unless: drop do: {
|
477
|
+
unless: drop? do: {
|
365
478
|
coll << x
|
366
479
|
}
|
367
480
|
} else: {
|
@@ -405,6 +518,18 @@ class Fancy {
|
|
405
518
|
|
406
519
|
alias_method: 'skip: for: 'drop:
|
407
520
|
|
521
|
+
def drop_last: amount (1) {
|
522
|
+
"""
|
523
|
+
@amount Amount of elements to drop from the end.
|
524
|
+
@return New @Array@ without last @amount elements.
|
525
|
+
|
526
|
+
Example:
|
527
|
+
[1,2,3,4] drop_last: 2 # => [1,2]
|
528
|
+
"""
|
529
|
+
|
530
|
+
first: (size - amount)
|
531
|
+
}
|
532
|
+
|
408
533
|
def reduce: block init_val: init_val {
|
409
534
|
"""
|
410
535
|
Calculates a value based on a given block to be called on an accumulator
|
@@ -416,7 +541,7 @@ class Fancy {
|
|
416
541
|
|
417
542
|
acc = init_val
|
418
543
|
each: |x| {
|
419
|
-
acc =
|
544
|
+
acc = block call: [acc, x]
|
420
545
|
}
|
421
546
|
acc
|
422
547
|
}
|
@@ -507,18 +632,19 @@ class Fancy {
|
|
507
632
|
[[1,2], [2,3,4], [-1]] superior_by: '< taking: 'first # => [-1]
|
508
633
|
"""
|
509
634
|
|
635
|
+
{ return nil } if: empty?
|
510
636
|
|
511
|
-
|
512
|
-
|
513
|
-
}
|
637
|
+
retval = first
|
638
|
+
retval_cmp = selection_block call: [retval]
|
514
639
|
|
515
|
-
|
516
|
-
|
517
|
-
if: (comparison_block call: [
|
518
|
-
retval
|
640
|
+
rest each: |p| {
|
641
|
+
cmp = selection_block call: [p]
|
642
|
+
if: (comparison_block call: [cmp, retval_cmp]) then: {
|
643
|
+
retval = p
|
644
|
+
retval_cmp = cmp
|
519
645
|
}
|
520
646
|
}
|
521
|
-
retval
|
647
|
+
retval
|
522
648
|
}
|
523
649
|
|
524
650
|
def max {
|
@@ -531,6 +657,20 @@ class Fancy {
|
|
531
657
|
superior_by: '>
|
532
658
|
}
|
533
659
|
|
660
|
+
def max_by: block {
|
661
|
+
"""
|
662
|
+
@block @Block@ by which to calculate the maximum value in @self.
|
663
|
+
@return Maximum value in @self based on @block.
|
664
|
+
|
665
|
+
Returns the maximum value in the Enumerable (via the '>' comparison message).
|
666
|
+
|
667
|
+
Example:
|
668
|
+
[[1,2,3], [1,2], [1]] max_by: @{ size } # => [1,2,3]
|
669
|
+
"""
|
670
|
+
|
671
|
+
superior_by: '> taking: block
|
672
|
+
}
|
673
|
+
|
534
674
|
def min {
|
535
675
|
"""
|
536
676
|
@return Minimum value in @self.
|
@@ -541,6 +681,57 @@ class Fancy {
|
|
541
681
|
superior_by: '<
|
542
682
|
}
|
543
683
|
|
684
|
+
def min_by: block {
|
685
|
+
"""
|
686
|
+
@block @Block@ by which to calculate the minimum value in @self.
|
687
|
+
@return Minimum value in @self based on @block.
|
688
|
+
|
689
|
+
Returns the minimum value in the Enumerable (via the '<' comparison message).
|
690
|
+
|
691
|
+
Example:
|
692
|
+
[[1,2,3], [1,2], [1]] min_by: @{ size } # => [1]
|
693
|
+
"""
|
694
|
+
|
695
|
+
superior_by: '< taking: block
|
696
|
+
}
|
697
|
+
|
698
|
+
def min_max {
|
699
|
+
"""
|
700
|
+
@return @Tuple@ of min and max value in @self.
|
701
|
+
|
702
|
+
If @self is empty, returns (nil, nil).
|
703
|
+
|
704
|
+
Example:
|
705
|
+
(1,2,3,4) min_max # => (1, 3)
|
706
|
+
"""
|
707
|
+
|
708
|
+
min_max_by: @{ identity }
|
709
|
+
}
|
710
|
+
|
711
|
+
def min_max_by: block {
|
712
|
+
"""
|
713
|
+
@block @Block@ to calculate the min and max value by.
|
714
|
+
@return @Tuple@ of min and max value based on @block in @self.
|
715
|
+
|
716
|
+
Calls @block with each element in @self to determine min and max values.
|
717
|
+
If @self is empty, returns (nil, nil).
|
718
|
+
|
719
|
+
Example:
|
720
|
+
(\"a\", \”bc\", \”def\") min_max_by: 'size # => (1, 3)
|
721
|
+
"""
|
722
|
+
|
723
|
+
min, max = nil, nil
|
724
|
+
min_val, max_val = nil, nil
|
725
|
+
each: |x| {
|
726
|
+
val = block call: [x]
|
727
|
+
{ min = val; min_val = x } unless: min
|
728
|
+
{ min = val; min_val = x } if: (val < min)
|
729
|
+
{ max = val; max_val = x } unless: max
|
730
|
+
{ max = val; max_val = x } if: (val > max)
|
731
|
+
}
|
732
|
+
(min_val, max_val)
|
733
|
+
}
|
734
|
+
|
544
735
|
def sum {
|
545
736
|
"""
|
546
737
|
Calculates the sum of all the elements in the @Enumerable
|
@@ -564,7 +755,7 @@ class Fancy {
|
|
564
755
|
@return Average value in @self (expecting @Number@s or Objects implementing @+ and @*).
|
565
756
|
"""
|
566
757
|
|
567
|
-
{ return 0 } if:
|
758
|
+
{ return 0 } if: empty?
|
568
759
|
sum to_f / size
|
569
760
|
}
|
570
761
|
|
@@ -593,6 +784,40 @@ class Fancy {
|
|
593
784
|
coll
|
594
785
|
}
|
595
786
|
|
787
|
+
def chunk_by: block {
|
788
|
+
"""
|
789
|
+
@block @Block@ to chunk @self by.
|
790
|
+
@return @Array@ of chunks, each including the return value of calling @block with elements in the chunk, as well as the elements themselves (within another @Array@).
|
791
|
+
|
792
|
+
Similar to @Fancy::Enumerable#partition_by:@ but includes the value of
|
793
|
+
calling @block with an element within the chunk.
|
794
|
+
|
795
|
+
Example:
|
796
|
+
[1,3,4,5,6,8,10] chunk_by: 'odd?
|
797
|
+
# => [[true, [1,3]], [false, [4]], [true, [5]], [false, [6,8,10]]]
|
798
|
+
"""
|
799
|
+
|
800
|
+
{ return [] } if: empty?
|
801
|
+
|
802
|
+
chunks = []
|
803
|
+
curr_chunk = []
|
804
|
+
initial = first
|
805
|
+
last_val = block call: [initial]
|
806
|
+
curr_chunk << initial
|
807
|
+
|
808
|
+
rest each: |x| {
|
809
|
+
val = block call: [x]
|
810
|
+
if: (val != last_val) then: {
|
811
|
+
chunks << [last_val, curr_chunk]
|
812
|
+
curr_chunk = []
|
813
|
+
}
|
814
|
+
curr_chunk << x
|
815
|
+
last_val = val
|
816
|
+
}
|
817
|
+
{ chunks << [last_val, curr_chunk] } unless: $ curr_chunk empty?
|
818
|
+
chunks
|
819
|
+
}
|
820
|
+
|
596
821
|
def random {
|
597
822
|
"""
|
598
823
|
@return Random element in @self.
|
@@ -601,20 +826,32 @@ class Fancy {
|
|
601
826
|
at: $ size random
|
602
827
|
}
|
603
828
|
|
604
|
-
def
|
829
|
+
def sort: comparison_block {
|
605
830
|
"""
|
606
|
-
@
|
831
|
+
@comparison_block @Block@ taking 2 arguments used to compare elements in a collection.
|
607
832
|
@return Sorted @Array@ of elements in @self.
|
608
833
|
|
609
834
|
Sorts a collection by a given comparison block.
|
610
835
|
"""
|
611
836
|
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
837
|
+
sort(&comparison_block)
|
838
|
+
}
|
839
|
+
|
840
|
+
def sort_by: block {
|
841
|
+
"""
|
842
|
+
@block @Block@ taking 1 argument used to extract a value to use for comparison.
|
843
|
+
@return Sorted @Array@ of elements in @self based on @block.
|
844
|
+
|
845
|
+
Sorts a collection by calling a @Block@ with every element
|
846
|
+
and using the return values for comparison.
|
847
|
+
|
848
|
+
Example:
|
849
|
+
[\"abc\", \"abcd\", \"ab\", \"a\", \"\"] sort_by: @{ size }
|
850
|
+
# => [\"\", \"a\", \"ab\", \"abc\", \"abcd\"]
|
851
|
+
"""
|
852
|
+
|
853
|
+
sort_by() |x| {
|
854
|
+
block call: [x]
|
618
855
|
}
|
619
856
|
}
|
620
857
|
|
@@ -650,6 +887,27 @@ class Fancy {
|
|
650
887
|
groups
|
651
888
|
}
|
652
889
|
|
890
|
+
def group_by: block {
|
891
|
+
"""
|
892
|
+
@block @Block@ used to group elements in @self by.
|
893
|
+
@return @Hash@ with elements in @self grouped by return value of calling @block with them.
|
894
|
+
|
895
|
+
Returns the elements grouped by @block in a @Hash@ (the keys being the
|
896
|
+
value of calling @block with the elements).
|
897
|
+
|
898
|
+
Example:
|
899
|
+
('foo, 1, 2, 'bar) group_by: @{ class }
|
900
|
+
# => <[Symbol => ['foo, 'bar], Fixnum => [1,2]]>
|
901
|
+
"""
|
902
|
+
|
903
|
+
h = <[]>
|
904
|
+
each: |x| {
|
905
|
+
group = h at: (block call: [x]) else_put: { [] }
|
906
|
+
group << x
|
907
|
+
}
|
908
|
+
h
|
909
|
+
}
|
910
|
+
|
653
911
|
def reverse {
|
654
912
|
"""
|
655
913
|
@return @self in reverse order.
|
@@ -800,5 +1058,38 @@ class Fancy {
|
|
800
1058
|
}
|
801
1059
|
result
|
802
1060
|
}
|
1061
|
+
|
1062
|
+
def one?: block {
|
1063
|
+
"""
|
1064
|
+
@block @Block@ to be used to check for a condition expected only once in @self.
|
1065
|
+
@return @true if @block yields @true only once for all elements in @self.
|
1066
|
+
|
1067
|
+
Example:
|
1068
|
+
(0,1,2) one?: 'odd? # => true
|
1069
|
+
(0,1,2) one?: 'even? # => false
|
1070
|
+
"""
|
1071
|
+
|
1072
|
+
got_one? = false
|
1073
|
+
each: |x| {
|
1074
|
+
if: (block call: [x]) then: {
|
1075
|
+
{ return false } if: got_one?
|
1076
|
+
got_one? = true
|
1077
|
+
}
|
1078
|
+
}
|
1079
|
+
return got_one?
|
1080
|
+
}
|
1081
|
+
|
1082
|
+
def none?: block {
|
1083
|
+
"""
|
1084
|
+
@block @Block@ to be used to check for a condition expected not once in @self.
|
1085
|
+
@return @true if none of the elements in @self called with @block yield @true.
|
1086
|
+
|
1087
|
+
Example:
|
1088
|
+
(0,2,4) none?: 'odd? # => true
|
1089
|
+
(0,2,5) none?: 'odd? # => false
|
1090
|
+
"""
|
1091
|
+
|
1092
|
+
any?: block . not
|
1093
|
+
}
|
803
1094
|
}
|
804
1095
|
}
|