fancy 0.3.0 → 0.3.1
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/{README → README.md} +33 -50
- data/Rakefile +6 -1
- data/bin/fyi +13 -10
- data/boot/fancy_ext.rb +1 -0
- data/boot/fancy_ext/block_env.rb +6 -2
- data/boot/fancy_ext/console.rb +4 -0
- data/boot/fancy_ext/object.rb +6 -0
- data/boot/rbx-compiler/compiler/ast/identifier.rb +5 -1
- data/boot/rbx-compiler/compiler/ast/match.rb +4 -5
- data/boot/rbx-compiler/compiler/ast/super.rb +1 -0
- data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/lexer.c +2316 -0
- data/boot/rbx-compiler/parser/lexer.h +315 -0
- data/boot/rbx-compiler/parser/parser.c +3105 -0
- data/boot/rbx-compiler/parser/parser.h +114 -0
- data/boot/rbx-compiler/parser/parser.rb +2 -2
- data/boot/rbx-compiler/parser/parser.y +3 -3
- data/doc/api/fancy.jsonp +1 -1
- data/doc/features.md +14 -3
- data/examples/async_send.fy +11 -0
- data/examples/fibonacci.fy +1 -1
- data/examples/future.fy +30 -0
- data/examples/futures.fy +14 -0
- data/examples/game_of_life.fy +1 -1
- data/examples/matchers.fy +1 -1
- data/examples/pattern_matching.fy +3 -3
- data/examples/stupid_quicksort.fy +1 -1
- data/examples/threads.fy +1 -1
- data/extconf.rb +7 -0
- data/lib/array.fy +25 -5
- data/lib/block.fy +20 -18
- data/lib/boot.fy +7 -2
- data/lib/class.fy +33 -2
- data/lib/compiler/ast.fy +2 -0
- data/lib/compiler/ast/assign.fy +5 -5
- data/lib/compiler/ast/async_send.fy +25 -0
- data/lib/compiler/ast/block.fy +3 -3
- data/lib/compiler/ast/future_send.fy +20 -0
- data/lib/compiler/ast/identifier.fy +13 -7
- data/lib/compiler/ast/match.fy +32 -22
- data/lib/compiler/ast/message_send.fy +4 -4
- data/lib/compiler/ast/method_def.fy +1 -1
- data/lib/compiler/ast/script.fy +2 -2
- data/lib/compiler/ast/super.fy +1 -0
- data/lib/compiler/compiler.fy +2 -0
- data/lib/documentation.fy +4 -4
- data/lib/enumerable.fy +14 -7
- data/lib/fancy_spec.fy +2 -2
- data/lib/fdoc.fy +7 -7
- data/lib/fiber.fy +11 -0
- data/lib/fiber_pool.fy +78 -0
- data/lib/file.fy +1 -1
- data/lib/future.fy +32 -0
- data/lib/hash.fy +5 -5
- data/lib/lazy_array.fy +23 -0
- data/lib/main.fy +35 -25
- data/lib/method.fy +1 -1
- data/lib/nil_class.fy +4 -0
- data/lib/object.fy +59 -7
- data/lib/package.fy +11 -2
- data/lib/package/installer.fy +50 -20
- data/lib/package/list.fy +34 -0
- data/lib/package/specification.fy +19 -1
- data/lib/parser/ext/Makefile +162 -0
- data/lib/parser/ext/lexer.c +2360 -0
- data/lib/parser/ext/lexer.h +315 -0
- data/lib/parser/ext/lexer.lex +4 -0
- data/lib/parser/ext/parser.c +3382 -0
- data/lib/parser/ext/parser.h +118 -0
- data/lib/parser/ext/parser.y +43 -3
- data/lib/parser/methods.fy +34 -7
- data/lib/parser/parse_error.fy +10 -0
- data/lib/proxy.fy +16 -0
- data/lib/rbx.fy +3 -0
- data/lib/rbx/array.fy +78 -40
- data/lib/rbx/block.fy +35 -1
- data/lib/rbx/class.fy +5 -3
- data/lib/rbx/code_loader.fy +6 -6
- data/lib/rbx/console.fy +1 -1
- data/lib/rbx/date.fy +12 -0
- data/lib/rbx/documentation.fy +5 -5
- data/lib/rbx/exception.fy +1 -1
- data/lib/rbx/fiber.fy +4 -8
- data/lib/rbx/file.fy +4 -3
- data/lib/rbx/fixnum.fy +1 -0
- data/lib/rbx/float.fy +1 -0
- data/lib/rbx/hash.fy +3 -2
- data/lib/rbx/io.fy +5 -5
- data/lib/rbx/match_data.fy +10 -0
- data/lib/rbx/method.fy +4 -4
- data/lib/rbx/no_method_error.fy +1 -1
- data/lib/rbx/object.fy +8 -15
- data/lib/rbx/regexp.fy +4 -0
- data/lib/rbx/string.fy +39 -1
- data/lib/rbx/symbol.fy +1 -1
- data/lib/rbx/system.fy +0 -6
- data/lib/rbx/thread.fy +5 -0
- data/lib/rbx/time.fy +14 -0
- data/lib/rbx/tuple.fy +1 -0
- data/lib/set.fy +1 -1
- data/lib/stack.fy +1 -1
- data/lib/string.fy +2 -2
- data/lib/thread_pool.fy +101 -0
- data/lib/tuple.fy +37 -6
- data/ruby_lib/fancy.rb +46 -0
- data/tests/block.fy +39 -0
- data/tests/class.fy +40 -1
- data/tests/file.fy +2 -2
- data/tests/hash.fy +7 -7
- data/tests/nil_class.fy +2 -2
- data/tests/object.fy +10 -2
- data/tests/pattern_matching.fy +18 -7
- metadata +34 -7
data/lib/boot.fy
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# boot.
|
1
|
+
# boot.fy
|
2
2
|
# This file gets loaded & run by Fancy automatically.
|
3
3
|
# It loads in Fancy's standard library & core classes.
|
4
4
|
|
@@ -31,6 +31,11 @@ require: "set"
|
|
31
31
|
require: "symbol"
|
32
32
|
require: "method"
|
33
33
|
require: "stack"
|
34
|
+
require: "proxy"
|
35
|
+
require: "thread_pool"
|
36
|
+
require: "fiber"
|
37
|
+
require: "fiber_pool"
|
38
|
+
require: "future"
|
34
39
|
|
35
40
|
# version holds fancy's version number
|
36
41
|
require: "version"
|
@@ -38,4 +43,4 @@ require: "argv"
|
|
38
43
|
|
39
44
|
require: "documentation"
|
40
45
|
|
41
|
-
require: "package.fy"
|
46
|
+
require: "package.fy"
|
data/lib/class.fy
CHANGED
@@ -50,6 +50,16 @@ class Class {
|
|
50
50
|
}
|
51
51
|
}
|
52
52
|
|
53
|
+
def read_slot: slotname {
|
54
|
+
"""
|
55
|
+
@slotname Name of slot to define a getter method for.
|
56
|
+
|
57
|
+
Defines a slot reader method for a given slotname.
|
58
|
+
"""
|
59
|
+
|
60
|
+
define_slot_reader: slotname
|
61
|
+
}
|
62
|
+
|
53
63
|
def write_slots: slots {
|
54
64
|
"""
|
55
65
|
@slots @Array@ of slotnames to define setter methods for.
|
@@ -62,6 +72,16 @@ class Class {
|
|
62
72
|
}
|
63
73
|
}
|
64
74
|
|
75
|
+
def write_slot: slotname {
|
76
|
+
"""
|
77
|
+
@slotname Name of slot to define a setter method for.
|
78
|
+
|
79
|
+
Defines a slot writer method for a given slotname.
|
80
|
+
"""
|
81
|
+
|
82
|
+
define_slot_writer: slotname
|
83
|
+
}
|
84
|
+
|
65
85
|
def read_write_slots: slots {
|
66
86
|
"""
|
67
87
|
@slots @Array@ of slotnames to define getter & setter methods for.
|
@@ -75,6 +95,17 @@ class Class {
|
|
75
95
|
}
|
76
96
|
}
|
77
97
|
|
98
|
+
def read_write_slot: slotname {
|
99
|
+
"""
|
100
|
+
@slotname Name of slot to define getter & setter methods for.
|
101
|
+
|
102
|
+
Defines slot reader & writer methods for a given slotname.
|
103
|
+
"""
|
104
|
+
|
105
|
+
define_slot_reader: slotname
|
106
|
+
define_slot_writer: slotname
|
107
|
+
}
|
108
|
+
|
78
109
|
def subclass?: class_obj {
|
79
110
|
"""
|
80
111
|
@class_obj Class object to check for, if @self is a subclass of @class_obj.
|
@@ -87,8 +118,8 @@ class Class {
|
|
87
118
|
true
|
88
119
|
} else: {
|
89
120
|
# take care of Object class, as Object is its own superclass
|
90
|
-
unless: (
|
91
|
-
|
121
|
+
unless: (superclass nil?) do: {
|
122
|
+
superclass subclass?: class_obj
|
92
123
|
}
|
93
124
|
}
|
94
125
|
}
|
data/lib/compiler/ast.fy
CHANGED
@@ -25,6 +25,8 @@ require: "ast/script"
|
|
25
25
|
require: "ast/expression_list"
|
26
26
|
require: "ast/identifier"
|
27
27
|
require: "ast/message_send"
|
28
|
+
require: "ast/future_send"
|
29
|
+
require: "ast/async_send"
|
28
30
|
require: "ast/method_def"
|
29
31
|
require: "ast/singleton_method_def"
|
30
32
|
require: "ast/super"
|
data/lib/compiler/ast/assign.fy
CHANGED
@@ -54,7 +54,7 @@ class Fancy AST {
|
|
54
54
|
@idents each_with_index: |ident idx| {
|
55
55
|
var = ident
|
56
56
|
value = MultipleAssignmentExpr new: @line index: idx
|
57
|
-
match ident string
|
57
|
+
match ident string {
|
58
58
|
case /^\*/ ->
|
59
59
|
value = SplatAssignmentExpr new: @line start_index: idx
|
60
60
|
var = Identifier from: (ident string rest) line: (ident line)
|
@@ -68,28 +68,28 @@ class Fancy AST {
|
|
68
68
|
class Identifier {
|
69
69
|
def bytecode: g assign: value {
|
70
70
|
pos(g)
|
71
|
-
Rubinius AST LocalVariableAssignment new(@line,
|
71
|
+
Rubinius AST LocalVariableAssignment new(@line, name, value) bytecode(g)
|
72
72
|
}
|
73
73
|
}
|
74
74
|
|
75
75
|
class InstanceVariable {
|
76
76
|
def bytecode: g assign: value {
|
77
77
|
pos(g)
|
78
|
-
Rubinius AST InstanceVariableAssignment new(@line,
|
78
|
+
Rubinius AST InstanceVariableAssignment new(@line, name, value) bytecode(g)
|
79
79
|
}
|
80
80
|
}
|
81
81
|
|
82
82
|
class ClassVariable {
|
83
83
|
def bytecode: g assign: value {
|
84
84
|
pos(g)
|
85
|
-
Rubinius AST ClassVariableAssignment new(@line,
|
85
|
+
Rubinius AST ClassVariableAssignment new(@line, name, value) bytecode(g)
|
86
86
|
}
|
87
87
|
}
|
88
88
|
|
89
89
|
class Constant {
|
90
90
|
def bytecode: g assign: value {
|
91
91
|
pos(g)
|
92
|
-
Rubinius AST ConstantAssignment new(@line,
|
92
|
+
Rubinius AST ConstantAssignment new(@line, name, value) bytecode(g)
|
93
93
|
}
|
94
94
|
}
|
95
95
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Fancy AST {
|
2
|
+
class AsyncSend : Node {
|
3
|
+
def initialize: @line message_send: @message_send {
|
4
|
+
}
|
5
|
+
|
6
|
+
def bytecode: g {
|
7
|
+
pos(g)
|
8
|
+
|
9
|
+
body = ExpressionList new: @line list: [@message_send]
|
10
|
+
block = BlockLiteral new: @line args: (BlockArgs new: @line) body: body
|
11
|
+
|
12
|
+
fiber = MessageSend new: @line \
|
13
|
+
message: (Identifier from: "new:" line: @line) \
|
14
|
+
to: (Identifier from: "Fiber" line: @line) \
|
15
|
+
args: (MessageArgs new: @line args: [block])
|
16
|
+
|
17
|
+
schedule_send = MessageSend new: @line \
|
18
|
+
message: (Identifier from: "add:" line: @line) \
|
19
|
+
to: (Identifier from: "Scheduler" line: @line) \
|
20
|
+
args: (MessageArgs new: @line args: [fiber])
|
21
|
+
|
22
|
+
schedule_send bytecode: g
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
data/lib/compiler/ast/block.fy
CHANGED
@@ -24,12 +24,12 @@ class Fancy AST {
|
|
24
24
|
# an identifier, use that as the message name in a send to
|
25
25
|
# self and use the result as the receiver value for the rest.
|
26
26
|
new_receiver = Identifier from: (@args args first to_s) line: @line
|
27
|
-
match first_expr
|
27
|
+
match first_expr {
|
28
28
|
case Identifier ->
|
29
29
|
@body expressions shift()
|
30
30
|
@body unshift_expression: $ MessageSend new: @line message: first_expr to: (new_receiver) args: (MessageArgs new: @line args: [])
|
31
31
|
case MessageSend ->
|
32
|
-
match first_expr receiver
|
32
|
+
match first_expr receiver {
|
33
33
|
case Self ->
|
34
34
|
first_expr receiver: new_receiver
|
35
35
|
case Identifier ->
|
@@ -72,7 +72,7 @@ class Fancy AST {
|
|
72
72
|
}
|
73
73
|
|
74
74
|
def required_args {
|
75
|
-
|
75
|
+
total_args
|
76
76
|
}
|
77
77
|
|
78
78
|
def create_locals: block {
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Fancy AST {
|
2
|
+
class FutureSend : Node {
|
3
|
+
def initialize: @line message_send: @message_send {
|
4
|
+
}
|
5
|
+
|
6
|
+
def bytecode: g {
|
7
|
+
pos(g)
|
8
|
+
|
9
|
+
body = ExpressionList new: @line list: [@message_send]
|
10
|
+
block = BlockLiteral new: @line args: (BlockArgs new: @line) body: body
|
11
|
+
|
12
|
+
future_send = MessageSend new: @line \
|
13
|
+
message: (Identifier from: "new:" line: @line) \
|
14
|
+
to: (Identifier from: "Future" line: @line) \
|
15
|
+
args: (MessageArgs new: @line args: [block])
|
16
|
+
|
17
|
+
future_send bytecode: g
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
@@ -37,7 +37,7 @@ class Fancy AST {
|
|
37
37
|
}
|
38
38
|
|
39
39
|
def self from: string line: line filename: filename (nil) {
|
40
|
-
type = match string
|
40
|
+
type = match string {
|
41
41
|
case "__FILE__" -> return CurrentFile new: line filename: filename
|
42
42
|
case "__LINE__" -> return CurrentLine new: line
|
43
43
|
case "self" -> return Self new: line
|
@@ -52,11 +52,17 @@ class Fancy AST {
|
|
52
52
|
|
53
53
|
def bytecode: g {
|
54
54
|
pos(g)
|
55
|
-
match @string
|
55
|
+
match @string {
|
56
56
|
case "true" -> g push_true()
|
57
57
|
case "false" -> g push_false()
|
58
58
|
case "nil" -> g push_nil()
|
59
|
-
case _ ->
|
59
|
+
case _ ->
|
60
|
+
if: (g state() scope() search_local(name)) then: {
|
61
|
+
Rubinius AST LocalVariableAccess new(@line, name) bytecode(g)
|
62
|
+
} else: {
|
63
|
+
ms = MessageSend new: @line message: self to: (Self new: @line) args: (MessageArgs new: @line args: [])
|
64
|
+
ms bytecode: g
|
65
|
+
}
|
60
66
|
}
|
61
67
|
}
|
62
68
|
}
|
@@ -65,7 +71,7 @@ class Fancy AST {
|
|
65
71
|
def initialize: @line string: @string {}
|
66
72
|
def bytecode: g {
|
67
73
|
pos(g)
|
68
|
-
Rubinius AST InstanceVariableAccess new(@line,
|
74
|
+
Rubinius AST InstanceVariableAccess new(@line, name) bytecode(g)
|
69
75
|
}
|
70
76
|
}
|
71
77
|
|
@@ -73,7 +79,7 @@ class Fancy AST {
|
|
73
79
|
def initialize: @line string: @string {}
|
74
80
|
def bytecode: g {
|
75
81
|
pos(g)
|
76
|
-
Rubinius AST ClassVariableAccess new(@line,
|
82
|
+
Rubinius AST ClassVariableAccess new(@line, name) bytecode(g)
|
77
83
|
}
|
78
84
|
}
|
79
85
|
|
@@ -81,7 +87,7 @@ class Fancy AST {
|
|
81
87
|
def initialize: @line string: @string {}
|
82
88
|
def bytecode: g {
|
83
89
|
pos(g)
|
84
|
-
Rubinius AST ConstantAccess new(@line,
|
90
|
+
Rubinius AST ConstantAccess new(@line, name) bytecode(g)
|
85
91
|
}
|
86
92
|
}
|
87
93
|
|
@@ -106,7 +112,7 @@ class Fancy AST {
|
|
106
112
|
|
107
113
|
def bytecode: g {
|
108
114
|
pos(g)
|
109
|
-
|
115
|
+
scoped bytecode(g)
|
110
116
|
}
|
111
117
|
}
|
112
118
|
|
data/lib/compiler/ast/match.fy
CHANGED
@@ -5,6 +5,37 @@ class Fancy AST {
|
|
5
5
|
}
|
6
6
|
|
7
7
|
|
8
|
+
def bytecode: g set_match_args: clause {
|
9
|
+
"Generates bytecode for setting match clause arguments, if needed"
|
10
|
+
|
11
|
+
g dup()
|
12
|
+
skip_create_locals_label = g new_label()
|
13
|
+
g gif(skip_create_locals_label)
|
14
|
+
|
15
|
+
# if match_arg is given, get a localvar slot and set the
|
16
|
+
# result of the === call to it
|
17
|
+
if: (clause match_args first) then: |marg| {
|
18
|
+
match_arg_var = g state() scope() new_local(marg)
|
19
|
+
@match_arg_vars << match_arg_var
|
20
|
+
g set_local(match_arg_var slot())
|
21
|
+
}
|
22
|
+
|
23
|
+
# for any remaining match arguments, set their values to
|
24
|
+
# whatever matcher[idx] returns (should be the matched data)
|
25
|
+
clause match_args rest each_with_index: |match_arg idx| {
|
26
|
+
idx = idx + 1 # we only want from index 1 onwards
|
27
|
+
g dup() # dup the matcher object
|
28
|
+
match_arg_var = g state() scope() new_local(match_arg)
|
29
|
+
@match_arg_vars << match_arg_var
|
30
|
+
FixnumLiteral new: @line value: idx . bytecode: g
|
31
|
+
g send('at:, 1)
|
32
|
+
g set_local(match_arg_var slot())
|
33
|
+
g pop()
|
34
|
+
}
|
35
|
+
|
36
|
+
skip_create_locals_label set!()
|
37
|
+
}
|
38
|
+
|
8
39
|
def bytecode: g {
|
9
40
|
pos(g)
|
10
41
|
|
@@ -25,28 +56,7 @@ class Fancy AST {
|
|
25
56
|
c expr bytecode: g
|
26
57
|
g swap()
|
27
58
|
g send(':===, 1)
|
28
|
-
|
29
|
-
# if match_arg is given, get a localvar slot and set the
|
30
|
-
# result of the === call to it
|
31
|
-
if: (c match_args first) then: |marg| {
|
32
|
-
match_arg_var = g state() scope() new_local(marg)
|
33
|
-
@match_arg_vars << match_arg_var
|
34
|
-
g set_local(match_arg_var slot())
|
35
|
-
}
|
36
|
-
|
37
|
-
# for any remaining match arguments, set their values to
|
38
|
-
# whatever matcher[idx] returns (should be the matched data)
|
39
|
-
c match_args rest each_with_index: |match_arg idx| {
|
40
|
-
idx = idx + 1 # we only want from index 1 onwards
|
41
|
-
g dup() # dup the matcher object
|
42
|
-
match_arg_var = g state() scope() new_local(match_arg)
|
43
|
-
@match_arg_vars << match_arg_var
|
44
|
-
FixnumLiteral new: @line value: idx . bytecode: g
|
45
|
-
g send('at:, 1)
|
46
|
-
g set_local(match_arg_var slot())
|
47
|
-
g pop()
|
48
|
-
}
|
49
|
-
|
59
|
+
bytecode: g set_match_args: c
|
50
60
|
g git(clause_labels[i])
|
51
61
|
}
|
52
62
|
g pop()
|
@@ -13,13 +13,13 @@ class Fancy AST {
|
|
13
13
|
@args bytecode: g
|
14
14
|
pos(g)
|
15
15
|
{ g allow_private() } if: (@receiver is_a?: Self)
|
16
|
-
sym = @name method_name: @receiver ruby_send:
|
17
|
-
if:
|
18
|
-
{ g push_nil() } unless:
|
16
|
+
sym = @name method_name: @receiver ruby_send: ruby_send?
|
17
|
+
if: has_splat? then: {
|
18
|
+
{ g push_nil() } unless: ruby_block?
|
19
19
|
g send_with_splat(sym, @args size, false)
|
20
20
|
return nil
|
21
21
|
}
|
22
|
-
if:
|
22
|
+
if: ruby_block? then: {
|
23
23
|
g send_with_block(sym, @args size, false)
|
24
24
|
} else: {
|
25
25
|
g send(sym, @args size, false)
|
@@ -3,7 +3,7 @@ class Fancy AST {
|
|
3
3
|
class MethodDef : Rubinius AST Define {
|
4
4
|
def initialize: @line name: @name args: @arguments body: @body access: @access {
|
5
5
|
@name = @name method_name: nil
|
6
|
-
|
6
|
+
generate_ivar_assignment
|
7
7
|
|
8
8
|
if: (@body empty?) then: {
|
9
9
|
@body unshift_expression: $ NilLiteral new: @line
|
data/lib/compiler/ast/script.fy
CHANGED
@@ -23,7 +23,7 @@ class Fancy AST {
|
|
23
23
|
def bytecode: g {
|
24
24
|
pos(g)
|
25
25
|
try {
|
26
|
-
|
26
|
+
push_script
|
27
27
|
|
28
28
|
# docs, code = body.expressions.partition do |s|
|
29
29
|
# s.kind_of?(Rubinius::AST::StringLiteral)
|
@@ -44,7 +44,7 @@ class Fancy AST {
|
|
44
44
|
# documentation.
|
45
45
|
# TODO: implement file documentation here.
|
46
46
|
} finally {
|
47
|
-
|
47
|
+
pop_script
|
48
48
|
}
|
49
49
|
}
|
50
50
|
}
|
data/lib/compiler/ast/super.fy
CHANGED
data/lib/compiler/compiler.fy
CHANGED
data/lib/documentation.fy
CHANGED
@@ -62,23 +62,23 @@ class Fancy Documentation {
|
|
62
62
|
Append docstring to the documentation for obj.
|
63
63
|
If obj has no documentation, one is created for it.
|
64
64
|
"""
|
65
|
-
doc =
|
65
|
+
doc = for: obj
|
66
66
|
doc if_do: {
|
67
67
|
doc docs << docstring
|
68
68
|
} else: {
|
69
|
-
doc =
|
69
|
+
doc = for: obj is: docstring
|
70
70
|
}
|
71
71
|
doc
|
72
72
|
}
|
73
73
|
|
74
74
|
def self formatter: name {
|
75
75
|
"Obtain a formatter by the given name. Returns a callable object"
|
76
|
-
|
76
|
+
formatters at: name
|
77
77
|
}
|
78
78
|
|
79
79
|
def self formatter: name is: callable {
|
80
80
|
"Register a callable object as formatter under name."
|
81
|
-
|
81
|
+
formatters at: name put: callable
|
82
82
|
}
|
83
83
|
|
84
84
|
def self formatters {
|
data/lib/enumerable.fy
CHANGED
@@ -154,7 +154,7 @@ class FancyEnumerable {
|
|
154
154
|
|
155
155
|
def take: amount {
|
156
156
|
i = 0
|
157
|
-
|
157
|
+
take_while: {
|
158
158
|
i = i + 1
|
159
159
|
i <= amount
|
160
160
|
}
|
@@ -162,7 +162,7 @@ class FancyEnumerable {
|
|
162
162
|
|
163
163
|
def drop: amount {
|
164
164
|
i = 0
|
165
|
-
|
165
|
+
drop_while: {
|
166
166
|
i = i + 1
|
167
167
|
i <= amount
|
168
168
|
}
|
@@ -178,6 +178,13 @@ class FancyEnumerable {
|
|
178
178
|
acc
|
179
179
|
}
|
180
180
|
|
181
|
+
def inject: val into: block {
|
182
|
+
"""
|
183
|
+
Same as reduce:init_val: but taking the initial value as first and the reducing block as second parameter.
|
184
|
+
"""
|
185
|
+
reduce: block init_val: val
|
186
|
+
}
|
187
|
+
|
181
188
|
def uniq {
|
182
189
|
"Returns a new Array with all unique values (double entries are skipped)."
|
183
190
|
|
@@ -202,11 +209,11 @@ class FancyEnumerable {
|
|
202
209
|
|
203
210
|
def empty? {
|
204
211
|
"Indicates, if the Enumerable is empty (has no elements)."
|
205
|
-
|
212
|
+
size == 0
|
206
213
|
}
|
207
214
|
|
208
215
|
def first {
|
209
|
-
|
216
|
+
each: |x| {
|
210
217
|
return x
|
211
218
|
}
|
212
219
|
}
|
@@ -230,7 +237,7 @@ class FancyEnumerable {
|
|
230
237
|
def superior_by: comparison_block {
|
231
238
|
"Returns the superiour element in the @Enumerable that has met the given comparison block with all other elements."
|
232
239
|
|
233
|
-
retval =
|
240
|
+
retval = first
|
234
241
|
each: |x| {
|
235
242
|
if: (comparison_block call: [x, retval]) then: {
|
236
243
|
retval = x
|
@@ -250,10 +257,10 @@ class FancyEnumerable {
|
|
250
257
|
}
|
251
258
|
|
252
259
|
def partition_by: block {
|
253
|
-
last = block call: [
|
260
|
+
last = block call: [first]
|
254
261
|
coll = []
|
255
262
|
tmp_coll = []
|
256
|
-
|
263
|
+
each: |x| {
|
257
264
|
tmp = block call: [x]
|
258
265
|
if: (tmp != last) then: {
|
259
266
|
coll << tmp_coll
|