eleetscript 0.0.2a
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.
- checksums.yaml +7 -0
- data/bin/eleet +89 -0
- data/lib/eleetscript.rb +18 -0
- data/lib/engine/eleet_engine.rb +58 -0
- data/lib/engine/eleet_to_ruby_wrapper.rb +25 -0
- data/lib/engine/ruby_to_eleet_wrapper.rb +22 -0
- data/lib/engine/values.rb +55 -0
- data/lib/lang/grammar.y +350 -0
- data/lib/lang/interpreter.rb +400 -0
- data/lib/lang/lexer.rb +92 -0
- data/lib/lang/nodes.rb +197 -0
- data/lib/lang/parser.output +11953 -0
- data/lib/lang/parser.rb +2300 -0
- data/lib/lang/runtime/array.rb +23 -0
- data/lib/lang/runtime/base_classes.rb +31 -0
- data/lib/lang/runtime/bootstrap.rb +3 -0
- data/lib/lang/runtime/class.rb +113 -0
- data/lib/lang/runtime/class_instance.rb +53 -0
- data/lib/lang/runtime/class_skeleton.rb +57 -0
- data/lib/lang/runtime/context.rb +263 -0
- data/lib/lang/runtime/eleetscript/enumerable.es +36 -0
- data/lib/lang/runtime/eleetscript/falseclass.es +25 -0
- data/lib/lang/runtime/eleetscript/integer.es +11 -0
- data/lib/lang/runtime/eleetscript/list.es +44 -0
- data/lib/lang/runtime/eleetscript/nilclass.es +5 -0
- data/lib/lang/runtime/eleetscript/number.es +13 -0
- data/lib/lang/runtime/eleetscript/object.es +49 -0
- data/lib/lang/runtime/eleetscript/pair.es +12 -0
- data/lib/lang/runtime/eleetscript/que.es +13 -0
- data/lib/lang/runtime/eleetscript/stack.es +14 -0
- data/lib/lang/runtime/eleetscript/string.es +34 -0
- data/lib/lang/runtime/eleetscript/trueclass.es +25 -0
- data/lib/lang/runtime/memory.rb +553 -0
- data/lib/lang/runtime/method.rb +32 -0
- data/lib/lang/runtime/method_hash.rb +40 -0
- data/lib/util/processed_key_hash.rb +34 -0
- metadata +79 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
module EleetScript
|
2
|
+
class EleetScriptArray < EleetScriptClass
|
3
|
+
attr_reader :hash, :array
|
4
|
+
|
5
|
+
def initialize(memory, super_class = nil)
|
6
|
+
super(memory, super_class)
|
7
|
+
@hash = {}
|
8
|
+
@array = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
str = "<EleetScriptArray"
|
13
|
+
hash_data = @hash.map do |key, value|
|
14
|
+
"#{key}=#{value}"
|
15
|
+
end
|
16
|
+
data = @array.dup.concat(hash_data)
|
17
|
+
if data.length > 0
|
18
|
+
str += "[" + data.join(", ") + "]"
|
19
|
+
end
|
20
|
+
str + ">"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module EleetScript
|
2
|
+
class ListBase
|
3
|
+
attr_reader :array_value, :hash_value
|
4
|
+
|
5
|
+
def initialize(nil_val)
|
6
|
+
@array_value = []
|
7
|
+
@hash_value = Hash.new(nil_val)
|
8
|
+
end
|
9
|
+
|
10
|
+
def merge!(o)
|
11
|
+
@array_value.concat(o.array_value)
|
12
|
+
@hash_value.merge!(o.hash_value)
|
13
|
+
end
|
14
|
+
|
15
|
+
def clone
|
16
|
+
dup
|
17
|
+
end
|
18
|
+
|
19
|
+
def dup
|
20
|
+
lst = ListBase.new
|
21
|
+
lst.array_value = @array_value.dup
|
22
|
+
lst.hash_value = @hash_value.dup
|
23
|
+
lst
|
24
|
+
end
|
25
|
+
|
26
|
+
def clear
|
27
|
+
@array_value.clear
|
28
|
+
@hash_value.clear
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require "lang/runtime/class_skeleton"
|
2
|
+
require "lang/runtime/class_instance"
|
3
|
+
require "lang/runtime/method_hash"
|
4
|
+
require "util/processed_key_hash"
|
5
|
+
|
6
|
+
module EleetScript
|
7
|
+
class EleetScriptClass < EleetScriptClassSkeleton
|
8
|
+
attr_accessor :methods, :class_vars, :context, :name
|
9
|
+
attr_reader :super_class
|
10
|
+
set_is_class
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def create(namespace, name, super_class = nil)
|
14
|
+
cls = EleetScriptClass.new(namespace, super_class)
|
15
|
+
cls.name = name
|
16
|
+
cls
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(namespace, super_class = nil)
|
21
|
+
@methods = MethodHash.new
|
22
|
+
@class_vars = ProcessedKeyHash.new
|
23
|
+
@class_vars.set_key_preprocessor do |key|
|
24
|
+
key[0..1] == "@@" ? key[2..-1] : key
|
25
|
+
end
|
26
|
+
@context = namespace.new_class_context(self, self)
|
27
|
+
@super_class = super_class
|
28
|
+
@ruby_value = self
|
29
|
+
end
|
30
|
+
alias :class_name :name
|
31
|
+
|
32
|
+
def call(method_name, arguments = [])
|
33
|
+
method = lookup(method_name.to_s)
|
34
|
+
if method
|
35
|
+
if method.arity == 3
|
36
|
+
method.call(self, arguments, @context)
|
37
|
+
else
|
38
|
+
method.call(self, arguments)
|
39
|
+
end
|
40
|
+
else
|
41
|
+
es_method_name = @context["String"].new_with_value(method_name.to_s)
|
42
|
+
call(NO_METHOD, arguments.dup.unshift(es_method_name))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def lookup(method_name)
|
47
|
+
method_name = method_name[0..1] == "@@" ? method_name : "@@#{method_name}"
|
48
|
+
method = @methods[method_name]
|
49
|
+
if method.nil? && has_super_class?
|
50
|
+
return super_class.lookup(method_name)
|
51
|
+
end
|
52
|
+
method
|
53
|
+
end
|
54
|
+
|
55
|
+
def instance_lookup(method_name)
|
56
|
+
method = @methods[method_name]
|
57
|
+
if method.nil? && has_super_class?
|
58
|
+
return super_class.instance_lookup(method_name)
|
59
|
+
end
|
60
|
+
method
|
61
|
+
end
|
62
|
+
|
63
|
+
def super_class
|
64
|
+
@super_class || @context["Object"]
|
65
|
+
end
|
66
|
+
|
67
|
+
def def(method_name, es_block = nil, &block)
|
68
|
+
method_name = method_name.to_s
|
69
|
+
if block_given?
|
70
|
+
@methods[method_name] = block
|
71
|
+
else
|
72
|
+
@methods[method_name] = es_method
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def class_def(method_name, es_block = nil, &block)
|
77
|
+
method_name = "@@#{method_name}"
|
78
|
+
if block_given?
|
79
|
+
@methods[method_name] = block
|
80
|
+
else
|
81
|
+
@methods[method_name] = es_method
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def new
|
86
|
+
EleetScriptClassInstance.new(@context, self)
|
87
|
+
end
|
88
|
+
|
89
|
+
def new_with_value(value)
|
90
|
+
cls = EleetScriptClassInstance.new(@context, self)
|
91
|
+
cls.ruby_value = value
|
92
|
+
cls
|
93
|
+
end
|
94
|
+
|
95
|
+
def to_s
|
96
|
+
"<EleetScriptClass \"#{name || "Unnamed"}\">"
|
97
|
+
end
|
98
|
+
|
99
|
+
def inspect
|
100
|
+
to_s[0..-2] + " @methods(#{@methods.keys.join(", ")})>"
|
101
|
+
end
|
102
|
+
|
103
|
+
def is_a?(value)
|
104
|
+
false
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def has_super_class?
|
110
|
+
@super_class || (@super_class.nil? && name != "Object")
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module EleetScript
|
2
|
+
class EleetScriptClassInstance < EleetScriptClassSkeleton
|
3
|
+
attr_accessor :instance_vars, :runtime_class, :context
|
4
|
+
set_is_instance
|
5
|
+
|
6
|
+
def initialize(class_context, runtime_class)
|
7
|
+
@instance_vars = ProcessedKeyHash.new
|
8
|
+
@instance_vars.set_key_preprocessor do |key|
|
9
|
+
key[0] == "@" ? key[1..-1] : key
|
10
|
+
end
|
11
|
+
@runtime_class = runtime_class
|
12
|
+
@context = class_context.new_instance_context(self)
|
13
|
+
@ruby_value = self
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(method_name, arguments = [])
|
17
|
+
# puts "Calling #{method_name} on #{self}"
|
18
|
+
method = @runtime_class.instance_lookup(method_name.to_s)
|
19
|
+
if method
|
20
|
+
if method.arity == 3
|
21
|
+
method.call(self, arguments, @context)
|
22
|
+
else
|
23
|
+
method.call(self, arguments)
|
24
|
+
end
|
25
|
+
else
|
26
|
+
es_method_name = @context["String"].new_with_value(method_name.to_s)
|
27
|
+
call(NO_METHOD, arguments.dup.unshift(es_method_name))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
"<EleetScriptClassInstance @instance_of=\"#{runtime_class.name || "Unnamed"}\">"
|
33
|
+
end
|
34
|
+
|
35
|
+
def inspect
|
36
|
+
to_s
|
37
|
+
end
|
38
|
+
|
39
|
+
def is_a?(value)
|
40
|
+
names = ["Object", runtime_class.name]
|
41
|
+
cur_class = runtime_class
|
42
|
+
while cur_class.super_class.name != "Object"
|
43
|
+
names << cur_class.super_class.name
|
44
|
+
cur_class = cur_class.super_class
|
45
|
+
end
|
46
|
+
names.include?(value)
|
47
|
+
end
|
48
|
+
|
49
|
+
def class_name
|
50
|
+
@runtime_class.name
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module EleetScript
|
2
|
+
NO_METHOD = "no_method"
|
3
|
+
|
4
|
+
class EleetScriptClassSkeleton
|
5
|
+
attr_accessor :ruby_value
|
6
|
+
attr_reader :memory
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def set_is_instance
|
10
|
+
self.class_eval do
|
11
|
+
def instance?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def set_is_class
|
18
|
+
self.class_eval do
|
19
|
+
def class?
|
20
|
+
true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def instance?
|
27
|
+
false
|
28
|
+
end
|
29
|
+
|
30
|
+
def class?
|
31
|
+
false
|
32
|
+
end
|
33
|
+
|
34
|
+
def is_a?(name)
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
38
|
+
def hash
|
39
|
+
if instance?
|
40
|
+
ruby_value.hash
|
41
|
+
else
|
42
|
+
name.hash
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def eql?(other)
|
47
|
+
if other.kind_of?(EleetScriptClassSkeleton)
|
48
|
+
if instance?
|
49
|
+
return call(:is, [other]).ruby_value
|
50
|
+
elsif class? && other.class?
|
51
|
+
return name == other.name
|
52
|
+
end
|
53
|
+
end
|
54
|
+
false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,263 @@
|
|
1
|
+
require "util/processed_key_hash"
|
2
|
+
|
3
|
+
module EleetScript
|
4
|
+
class BaseContext
|
5
|
+
@@_init_funcs = []
|
6
|
+
|
7
|
+
attr_reader :constants, :local_vars, :global_vars, :namespaces
|
8
|
+
attr_accessor :current_self, :current_class
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def init_with(*func_symbols)
|
12
|
+
@@_init_funcs += func_symbols
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(*args)
|
17
|
+
init(args)
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def es_nil
|
22
|
+
@_es_nil ||= self["nil"]
|
23
|
+
end
|
24
|
+
|
25
|
+
def root_ns
|
26
|
+
@parent_context ? @parent_context.root_ns : nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def namespaces
|
30
|
+
@parent_context ? @parent_context.namespaces : {}
|
31
|
+
end
|
32
|
+
|
33
|
+
def global_vars
|
34
|
+
@parent_context ? @parent_context.global_vars : {}
|
35
|
+
end
|
36
|
+
|
37
|
+
def instance_vars
|
38
|
+
@current_self.instance_vars
|
39
|
+
end
|
40
|
+
|
41
|
+
def class_vars
|
42
|
+
@current_self.class_vars
|
43
|
+
end
|
44
|
+
|
45
|
+
def local_var(name, value = nil)
|
46
|
+
if value
|
47
|
+
local_vars[name] = value
|
48
|
+
else
|
49
|
+
local_vars[name] || es_nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def [](key)
|
54
|
+
store = fetch_var_store(key)
|
55
|
+
if store[key]
|
56
|
+
store[key]
|
57
|
+
elsif @parent_context
|
58
|
+
@parent_context[key]
|
59
|
+
else
|
60
|
+
es_nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def []=(key, value)
|
65
|
+
store = fetch_var_store(key)
|
66
|
+
store[key] = value
|
67
|
+
end
|
68
|
+
|
69
|
+
def respond_to_missing?(name, incl_priv = false)
|
70
|
+
@parent_context && @parent_context.respond_to?(name, incl_priv)
|
71
|
+
end
|
72
|
+
|
73
|
+
def method_missing(name, *args)
|
74
|
+
if @parent_context && @parent_context.respond_to?(name)
|
75
|
+
@parent_context.send(name, *args)
|
76
|
+
else
|
77
|
+
super(name, *args)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
protected
|
82
|
+
|
83
|
+
def fetch_var_store(key)
|
84
|
+
if key[0] =~ /[A-Z]/
|
85
|
+
constants
|
86
|
+
elsif key[0] =~ /[a-z_]/
|
87
|
+
local_vars
|
88
|
+
elsif key[0] == "$"
|
89
|
+
global_vars
|
90
|
+
elsif key[0..1] == "@@"
|
91
|
+
class_vars
|
92
|
+
elsif key[0] == "@"
|
93
|
+
instance_vars
|
94
|
+
else
|
95
|
+
{}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def parent_context=(context)
|
100
|
+
@parent_context = context
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def init(args)
|
106
|
+
throw "Arguments for new context should contain a current self and current class (even if both are nil)." if args.length < 2
|
107
|
+
@current_self = args.shift
|
108
|
+
cc = if args.length > 0
|
109
|
+
args.shift
|
110
|
+
else
|
111
|
+
nil
|
112
|
+
end
|
113
|
+
@current_class = if cc.nil?
|
114
|
+
if @current_self
|
115
|
+
if @current_self.class?
|
116
|
+
@current_self
|
117
|
+
else
|
118
|
+
@current_self.runtime_class
|
119
|
+
end
|
120
|
+
else
|
121
|
+
nil
|
122
|
+
end
|
123
|
+
else
|
124
|
+
cc
|
125
|
+
end
|
126
|
+
@parent_context = nil
|
127
|
+
@local_vars = ProcessedKeyHash.new
|
128
|
+
@constants = ProcessedKeyHash.new
|
129
|
+
@global_vars = {}
|
130
|
+
@namespaces = {}
|
131
|
+
@@_init_funcs.each do |symbol|
|
132
|
+
send(symbol, *args) if respond_to?(symbol, true)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
class NamespaceContext < BaseContext
|
138
|
+
attr_reader :global_vars
|
139
|
+
|
140
|
+
init_with :init_namespace
|
141
|
+
|
142
|
+
def namespace(name)
|
143
|
+
ns = @namespaces[name]
|
144
|
+
if ns.nil? && @parent_context
|
145
|
+
ns = @parent_context.namespaces[ns]
|
146
|
+
end
|
147
|
+
ns
|
148
|
+
end
|
149
|
+
|
150
|
+
def add_namespace(name, value)
|
151
|
+
@namespaces[name] = value
|
152
|
+
end
|
153
|
+
|
154
|
+
def global_vars
|
155
|
+
if @root_ns == self
|
156
|
+
@global_vars
|
157
|
+
else
|
158
|
+
@root_ns.global_vars
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def es_nil
|
163
|
+
@root_ns["nil"]
|
164
|
+
end
|
165
|
+
|
166
|
+
def root_ns
|
167
|
+
@root_ns
|
168
|
+
end
|
169
|
+
|
170
|
+
def new_class_context(current_self, current_class = nil)
|
171
|
+
ctx = ClassContext.new(current_self, current_class)
|
172
|
+
ctx.parent_context = self
|
173
|
+
ctx
|
174
|
+
end
|
175
|
+
|
176
|
+
def new_namespace_context
|
177
|
+
ctx = NamespaceContext.new(@current_self, @current_class, @root_ns)
|
178
|
+
ctx.parent_context = self
|
179
|
+
ctx
|
180
|
+
end
|
181
|
+
|
182
|
+
private
|
183
|
+
|
184
|
+
def init_namespace(root = nil)
|
185
|
+
if @root_ns == nil
|
186
|
+
@root_ns = self
|
187
|
+
@global_vars = ProcessedKeyHash.new
|
188
|
+
@global_vars.set_key_preprocessor do |key|
|
189
|
+
key[0] == "$" ? key[1..-1] : key
|
190
|
+
end
|
191
|
+
else
|
192
|
+
@root_ns = root
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
class ClassContext < BaseContext
|
198
|
+
def class_vars
|
199
|
+
@current_class.class_vars
|
200
|
+
end
|
201
|
+
|
202
|
+
def instance_vars
|
203
|
+
@parent_context ? @parent_context.instance_vars : {}
|
204
|
+
end
|
205
|
+
|
206
|
+
def new_instance_context(instance_self)
|
207
|
+
ctx = ClassInstanceContext.new(instance_self, current_class)
|
208
|
+
ctx.parent_context = self
|
209
|
+
ctx
|
210
|
+
end
|
211
|
+
|
212
|
+
def new_method_context(lambda_context = nil)
|
213
|
+
ctx = MethodContext.new(current_self, current_class, lambda_context)
|
214
|
+
ctx.parent_context = self
|
215
|
+
ctx
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
class ClassInstanceContext < BaseContext
|
220
|
+
def current_class
|
221
|
+
@parent_context.current_class
|
222
|
+
end
|
223
|
+
|
224
|
+
def local_vars
|
225
|
+
{}
|
226
|
+
end
|
227
|
+
|
228
|
+
def new_method_context(lambda_context = nil)
|
229
|
+
ctx = MethodContext.new(current_self, current_class, lambda_context)
|
230
|
+
ctx.parent_context = self
|
231
|
+
ctx
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
class MethodContext < BaseContext
|
236
|
+
init_with :handle_lambda_context
|
237
|
+
|
238
|
+
def local_var(name, value = nil)
|
239
|
+
if value
|
240
|
+
if @lambda_context && (val = @lambda_context.local_var(name))
|
241
|
+
@lambda_context.local_var(name, value)
|
242
|
+
else
|
243
|
+
local_vars[name] = value
|
244
|
+
end
|
245
|
+
else
|
246
|
+
val = super
|
247
|
+
if val == es_nil && @lambda_context
|
248
|
+
@lambda_context.local_var(name)
|
249
|
+
elsif val
|
250
|
+
val
|
251
|
+
else
|
252
|
+
es_nil
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
private
|
258
|
+
|
259
|
+
def handle_lambda_context(lambda_context)
|
260
|
+
@lambda_context = lambda_context
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Enumerable
|
2
|
+
[] do |name|
|
3
|
+
cname = class_name
|
4
|
+
Errors < "Class %cname has not implemented [] which is required for Enumerable"
|
5
|
+
end
|
6
|
+
|
7
|
+
[]= do |name, value|
|
8
|
+
cname = class_name
|
9
|
+
Errors < "Class %cname has not implemented []= which is required for Enumerable"
|
10
|
+
end
|
11
|
+
|
12
|
+
length do |name, value|
|
13
|
+
cname = class_name
|
14
|
+
Errors < "Class %cname has not implemented length which is required for Enumerable"
|
15
|
+
end
|
16
|
+
|
17
|
+
each do |iter|
|
18
|
+
if lambda? and iter.kind_of?(Lambda)
|
19
|
+
i = 0
|
20
|
+
while i < self.length
|
21
|
+
iter.call(self[i], i)
|
22
|
+
i += 1
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
map do |iter|
|
28
|
+
if lambda? and iter.kind_of?(Lambda)
|
29
|
+
arr = []
|
30
|
+
each -> { |item, key|
|
31
|
+
arr < iter.call(item, key)
|
32
|
+
}
|
33
|
+
end
|
34
|
+
arr
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class List
|
2
|
+
< do |value|
|
3
|
+
self.push(value)
|
4
|
+
end
|
5
|
+
|
6
|
+
+ do |other|
|
7
|
+
if other.kind_of?(List)
|
8
|
+
self.merge!(other)
|
9
|
+
else
|
10
|
+
self
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
each do
|
15
|
+
if lambda?
|
16
|
+
keys = self.keys
|
17
|
+
i = 0
|
18
|
+
while i < keys.length
|
19
|
+
key = keys[i]
|
20
|
+
lambda.call(self[key], key)
|
21
|
+
i += 1
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
inject do |val, iter|
|
27
|
+
if lambda?
|
28
|
+
self.each -> { |item, key|
|
29
|
+
val = lambda.call(val, item, key)
|
30
|
+
}
|
31
|
+
end
|
32
|
+
val
|
33
|
+
end
|
34
|
+
|
35
|
+
sum do
|
36
|
+
inject(0) -> { |sum, val|
|
37
|
+
if val.kind_of?(Number)
|
38
|
+
sum + val
|
39
|
+
else
|
40
|
+
sum
|
41
|
+
end
|
42
|
+
}
|
43
|
+
end
|
44
|
+
end
|