nydp 0.2.3 → 0.2.5
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 +4 -4
- data/bin/nydp +1 -1
- data/lib/lisp/core-000.nydp +1 -0
- data/lib/lisp/core-010-precompile.nydp +15 -15
- data/lib/lisp/core-012-utils.nydp +6 -5
- data/lib/lisp/core-020-utils.nydp +20 -6
- data/lib/lisp/core-030-syntax.nydp +14 -16
- data/lib/lisp/core-035-flow-control.nydp +26 -8
- data/lib/lisp/core-040-utils.nydp +4 -15
- data/lib/lisp/core-041-string-utils.nydp +3 -3
- data/lib/lisp/core-043-list-utils.nydp +81 -16
- data/lib/lisp/core-045-dox-utils.nydp +2 -2
- data/lib/lisp/core-060-benchmarking.nydp +92 -27
- data/lib/lisp/tests/all-examples.nydp +20 -0
- data/lib/lisp/tests/any-examples.nydp +28 -0
- data/lib/lisp/tests/builtin-tests.nydp +3 -1
- data/lib/lisp/tests/collect-tests.nydp +10 -0
- data/lib/lisp/tests/curry-tests.nydp +7 -2
- data/lib/lisp/tests/error-tests.nydp +11 -0
- data/lib/lisp/tests/foundation-test.nydp +66 -0
- data/lib/lisp/tests/len-examples.nydp +1 -0
- data/lib/lisp/tests/list-gsub-examples.nydp +25 -0
- data/lib/lisp/tests/list-match-examples.nydp +40 -0
- data/lib/lisp/tests/list-tests.nydp +13 -0
- data/lib/lisp/tests/none-examples.nydp +16 -0
- data/lib/lisp/tests/parser-tests.nydp +4 -5
- data/lib/lisp/tests/quasiquote-examples.nydp +2 -0
- data/lib/lisp/tests/syntax-tests.nydp +3 -2
- data/lib/lisp/tests/tuples-examples.nydp +2 -2
- data/lib/nydp.rb +50 -18
- data/lib/nydp/assignment.rb +3 -1
- data/lib/nydp/builtin.rb +15 -13
- data/lib/nydp/builtin/error.rb +1 -1
- data/lib/nydp/builtin/handle_error.rb +8 -2
- data/lib/nydp/builtin/parse_in_string.rb +1 -1
- data/lib/nydp/builtin/plus.rb +4 -4
- data/lib/nydp/closure.rb +5 -1
- data/lib/nydp/compiler.rb +2 -3
- data/lib/nydp/cond.rb +134 -13
- data/lib/nydp/context_symbol.rb +4 -1
- data/lib/nydp/error.rb +8 -0
- data/lib/nydp/function_invocation.rb +46 -48
- data/lib/nydp/helper.rb +15 -0
- data/lib/nydp/interpreted_function.rb +10 -14
- data/lib/nydp/lexical_context.rb +13 -2
- data/lib/nydp/lexical_context_builder.rb +28 -13
- data/lib/nydp/pair.rb +35 -36
- data/lib/nydp/parser.rb +3 -0
- data/lib/nydp/runner.rb +4 -32
- data/lib/nydp/string_atom.rb +3 -2
- data/lib/nydp/symbol.rb +1 -1
- data/lib/nydp/symbol_lookup.rb +9 -1
- data/lib/nydp/truth.rb +1 -1
- data/lib/nydp/version.rb +1 -1
- data/lib/nydp/vm.rb +2 -2
- data/nydp.gemspec +1 -1
- data/spec/error_spec.rb +14 -4
- data/spec/hash_non_hash_behaviour_spec.rb +19 -12
- data/spec/hash_spec.rb +0 -13
- data/spec/pair_spec.rb +17 -3
- data/spec/spec_helper.rb +13 -1
- data/spec/symbol_spec.rb +1 -1
- metadata +9 -4
data/lib/nydp/context_symbol.rb
CHANGED
@@ -31,13 +31,16 @@ class #{cname} < Nydp::ContextSymbol
|
|
31
31
|
|
32
32
|
def assign value, ctx
|
33
33
|
ctx#{getctx}.#{set_index}
|
34
|
+
rescue StandardError => e
|
35
|
+
raise "problem in \#{self.class.name}#assign, name is \#{@name}, depth is \#{depth}, index is #{binding_index}"
|
34
36
|
end
|
35
37
|
|
36
38
|
def execute vm
|
37
39
|
vm.push_arg value vm.current_context
|
38
40
|
end
|
39
41
|
|
40
|
-
def
|
42
|
+
def depth ; #{depth} ; end
|
43
|
+
def inspect ; to_s ; end
|
41
44
|
def to_s ; "[#{depth}##{binding_index}]\#{@name}" ; end
|
42
45
|
end
|
43
46
|
KLASS
|
data/lib/nydp/error.rb
CHANGED
@@ -9,17 +9,20 @@ module Nydp
|
|
9
9
|
@source_expression = source_expression
|
10
10
|
end
|
11
11
|
|
12
|
-
def handle e, f, args
|
12
|
+
def handle e, f, invoker, *args
|
13
13
|
case e
|
14
14
|
when Nydp::Error, InvocationFailed
|
15
|
-
raise
|
15
|
+
raise
|
16
16
|
else
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
if e.is_a?(NoMethodError) && !f.respond_to?(invoker)
|
18
|
+
raise InvocationFailed.new("#{f} is not a function")
|
19
|
+
else
|
20
|
+
msg = args.map { |a| " #{a.inspect}"}.join("\n")
|
21
|
+
msg = "failed to execute invocation #{f.inspect}\n#{msg}"
|
22
|
+
msg += "\nsource was #{source.inspect}"
|
23
|
+
msg += "\nfunction name was #{source.car.inspect}"
|
24
|
+
raise InvocationFailed.new msg
|
25
|
+
end
|
23
26
|
end
|
24
27
|
end
|
25
28
|
|
@@ -32,8 +35,8 @@ module Nydp
|
|
32
35
|
def execute vm
|
33
36
|
f = vm.args.pop
|
34
37
|
f.invoke_1 vm
|
35
|
-
rescue
|
36
|
-
handle e, f,
|
38
|
+
rescue StandardError => e
|
39
|
+
handle e, f, :invoke_1
|
37
40
|
end
|
38
41
|
end
|
39
42
|
|
@@ -41,10 +44,9 @@ module Nydp
|
|
41
44
|
def execute vm
|
42
45
|
arg = vm.args.pop
|
43
46
|
f = vm.args.pop
|
44
|
-
|
45
47
|
f.invoke_2 vm, arg
|
46
|
-
rescue
|
47
|
-
handle e, f,
|
48
|
+
rescue StandardError => e
|
49
|
+
handle e, f, :invoke_2, arg
|
48
50
|
end
|
49
51
|
end
|
50
52
|
|
@@ -54,8 +56,8 @@ module Nydp
|
|
54
56
|
arg_0 = vm.args.pop
|
55
57
|
f = vm.args.pop
|
56
58
|
f.invoke_3 vm, arg_0, arg_1
|
57
|
-
rescue
|
58
|
-
handle e, f,
|
59
|
+
rescue StandardError => e
|
60
|
+
handle e, f, :invoke_3, arg_0, arg_1
|
59
61
|
end
|
60
62
|
end
|
61
63
|
|
@@ -66,8 +68,8 @@ module Nydp
|
|
66
68
|
arg_0 = vm.args.pop
|
67
69
|
f = vm.args.pop
|
68
70
|
f.invoke_4 vm, arg_0, arg_1, arg_2
|
69
|
-
rescue
|
70
|
-
handle e, f,
|
71
|
+
rescue StandardError => e
|
72
|
+
handle e, f, :invoke_4, arg_0, arg_1, arg_2
|
71
73
|
end
|
72
74
|
end
|
73
75
|
|
@@ -80,13 +82,16 @@ module Nydp
|
|
80
82
|
def execute vm
|
81
83
|
args = vm.pop_args @arg_count
|
82
84
|
args.car.invoke vm, args.cdr
|
83
|
-
rescue
|
84
|
-
handle e, args.car, args.cdr
|
85
|
+
rescue StandardError => e
|
86
|
+
handle e, args.car, :invoke, args.cdr
|
85
87
|
end
|
86
88
|
end
|
87
89
|
|
88
90
|
# TODO generate various Invocation_XXX classes on-demand instead of hand_coding them all up front
|
91
|
+
SIGS = Set.new
|
92
|
+
|
89
93
|
class Invocation_LEX < Invocation::Base
|
94
|
+
SIGS << self.name
|
90
95
|
def initialize expr, src
|
91
96
|
super src
|
92
97
|
@sym = expr.car
|
@@ -94,12 +99,13 @@ module Nydp
|
|
94
99
|
|
95
100
|
def execute vm
|
96
101
|
@sym.value(vm.current_context).invoke_1 vm
|
97
|
-
rescue
|
98
|
-
handle e, @sym.value(vm.current_context),
|
102
|
+
rescue StandardError => e
|
103
|
+
handle e, @sym.value(vm.current_context), :invoke_1
|
99
104
|
end
|
100
105
|
end
|
101
106
|
|
102
107
|
class Invocation_SYM < Invocation::Base
|
108
|
+
SIGS << self.name
|
103
109
|
def initialize expr, src
|
104
110
|
super src
|
105
111
|
@sym = expr.car
|
@@ -107,12 +113,13 @@ module Nydp
|
|
107
113
|
|
108
114
|
def execute vm
|
109
115
|
@sym.value.invoke_1 vm
|
110
|
-
rescue
|
111
|
-
handle e, @sym.value,
|
116
|
+
rescue StandardError => e
|
117
|
+
handle e, @sym.value, :invoke_1
|
112
118
|
end
|
113
119
|
end
|
114
120
|
|
115
121
|
class Invocation_LEX_LEX < Invocation::Base
|
122
|
+
SIGS << self.name
|
116
123
|
def initialize expr, src
|
117
124
|
super src
|
118
125
|
@lex0 = expr.car
|
@@ -123,12 +130,13 @@ module Nydp
|
|
123
130
|
fn = @lex0.value(vm.current_context)
|
124
131
|
a0 = @lex1.value(vm.current_context)
|
125
132
|
fn.invoke_2 vm, a0
|
126
|
-
rescue
|
127
|
-
handle e, fn,
|
133
|
+
rescue StandardError => e
|
134
|
+
handle e, fn, :invoke_2, a0
|
128
135
|
end
|
129
136
|
end
|
130
137
|
|
131
138
|
class Invocation_SYM_LEX < Invocation::Base
|
139
|
+
SIGS << self.name
|
132
140
|
def initialize expr, src
|
133
141
|
super src
|
134
142
|
@sym = expr.car
|
@@ -139,12 +147,13 @@ module Nydp
|
|
139
147
|
fn = @sym.value
|
140
148
|
a0 = @lex.value(vm.current_context)
|
141
149
|
fn.invoke_2 vm, a0
|
142
|
-
rescue
|
143
|
-
handle e, fn,
|
150
|
+
rescue StandardError => e
|
151
|
+
handle e, fn, :invoke_2, a0
|
144
152
|
end
|
145
153
|
end
|
146
154
|
|
147
155
|
class Invocation_LEX_LEX_LEX < Invocation::Base
|
156
|
+
SIGS << self.name
|
148
157
|
def initialize expr, src
|
149
158
|
super src
|
150
159
|
@lex_0 = expr.car
|
@@ -157,12 +166,13 @@ module Nydp
|
|
157
166
|
a0 = @lex_1.value(vm.current_context)
|
158
167
|
a1 = @lex_2.value(vm.current_context)
|
159
168
|
fn.invoke_3 vm, a0, a1
|
160
|
-
rescue
|
161
|
-
handle e, fn,
|
169
|
+
rescue StandardError => e
|
170
|
+
handle e, fn, :invoke_3, a0, a1
|
162
171
|
end
|
163
172
|
end
|
164
173
|
|
165
174
|
class Invocation_SYM_LEX_LEX < Invocation::Base
|
175
|
+
SIGS << self.name
|
166
176
|
def initialize expr, src
|
167
177
|
super src
|
168
178
|
@sym = expr.car
|
@@ -175,8 +185,8 @@ module Nydp
|
|
175
185
|
a0 = @lex_0.value(vm.current_context)
|
176
186
|
a1 = @lex_1.value(vm.current_context)
|
177
187
|
fn.invoke_3 vm, a0, a1
|
178
|
-
rescue
|
179
|
-
handle e, fn,
|
188
|
+
rescue StandardError => e
|
189
|
+
handle e, fn, :invoke_3, a0, a1
|
180
190
|
end
|
181
191
|
end
|
182
192
|
end
|
@@ -184,29 +194,17 @@ module Nydp
|
|
184
194
|
class FunctionInvocation
|
185
195
|
extend Helper
|
186
196
|
attr_accessor :function_instruction, :argument_instructions
|
197
|
+
@@put = nil
|
187
198
|
|
188
|
-
def self.sig klass
|
189
|
-
case klass
|
190
|
-
when Nydp::Symbol ; "SYM"
|
191
|
-
when Nydp::ContextSymbol ; "LEX"
|
192
|
-
when Nydp::Literal ; "LIT"
|
193
|
-
when Nydp::FunctionInvocation ; "NVK"
|
194
|
-
when Nydp::Invocation::Base ; "NVB"
|
195
|
-
when Nydp::InterpretedFunction ; "IFN"
|
196
|
-
when Nydp::Cond ; "CND"
|
197
|
-
when Nydp::Assignment ; "ASN"
|
198
|
-
else ; raise "no sig for #{klass.class.name}"
|
199
|
-
end
|
200
|
-
end
|
201
199
|
def self.build expression, bindings
|
202
200
|
compiled = Compiler.compile_each(expression, bindings)
|
203
201
|
invocation_sig = compiled.map { |x| sig x }.join("_")
|
204
202
|
|
205
203
|
cname = "Invocation_#{invocation_sig}"
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
return
|
204
|
+
|
205
|
+
exists = Invocation::SIGS.include? "Nydp::Invocation::#{cname}"
|
206
|
+
if exists
|
207
|
+
return Nydp::Invocation.const_get(cname).new(compiled, expression)
|
210
208
|
end
|
211
209
|
|
212
210
|
invocation = cons case expression.size
|
data/lib/nydp/helper.rb
CHANGED
@@ -30,6 +30,21 @@ module Nydp
|
|
30
30
|
def n2r obj ; Nydp.n2r obj ; end
|
31
31
|
def r2n obj, ns ; Nydp.r2n obj, ns ; end
|
32
32
|
|
33
|
+
def sig klass
|
34
|
+
case klass
|
35
|
+
when Nydp::Symbol ; "SYM"
|
36
|
+
when Nydp::ContextSymbol ; "LEX"
|
37
|
+
when Nydp::Literal ; "LIT"
|
38
|
+
when Nydp::FunctionInvocation ; "NVK"
|
39
|
+
when Nydp::Invocation::Base ; "NVB"
|
40
|
+
when Nydp::InterpretedFunction ; "IFN"
|
41
|
+
when Nydp::Cond ; "CND"
|
42
|
+
when Nydp::CondBase ; "CND"
|
43
|
+
when Nydp::Assignment ; "ASN"
|
44
|
+
else ; raise "no sig for #{klass.class.name}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
33
48
|
def sym? expr, name
|
34
49
|
expr.is_a?(Nydp::Symbol) && (expr.is? name)
|
35
50
|
end
|
@@ -17,35 +17,27 @@ module Nydp
|
|
17
17
|
|
18
18
|
def invoke_1 vm, parent_context
|
19
19
|
vm.instructions.push self.body
|
20
|
-
vm.contexts.push
|
20
|
+
vm.contexts.push set_args_0 parent_context
|
21
21
|
end
|
22
22
|
|
23
23
|
def invoke_2 vm, parent_context, arg
|
24
|
-
lc = LexicalContext.new parent_context
|
25
|
-
set_args_1 lc, arg
|
26
24
|
vm.instructions.push self.body
|
27
|
-
vm.contexts.push
|
25
|
+
vm.contexts.push set_args_1(parent_context, arg)
|
28
26
|
end
|
29
27
|
|
30
28
|
def invoke_3 vm, parent_context, arg_0, arg_1
|
31
|
-
lc = LexicalContext.new parent_context
|
32
|
-
set_args_2 lc, arg_0, arg_1
|
33
29
|
vm.instructions.push self.body
|
34
|
-
vm.contexts.push
|
30
|
+
vm.contexts.push set_args_2(parent_context, arg_0, arg_1)
|
35
31
|
end
|
36
32
|
|
37
33
|
def invoke_4 vm, parent_context, arg_0, arg_1, arg_2
|
38
|
-
lc = LexicalContext.new parent_context
|
39
|
-
set_args_3 lc, arg_0, arg_1, arg_2
|
40
34
|
vm.instructions.push self.body
|
41
|
-
vm.contexts.push
|
35
|
+
vm.contexts.push set_args_3(parent_context, arg_0, arg_1, arg_2)
|
42
36
|
end
|
43
37
|
|
44
38
|
def invoke vm, parent_context, arg_values
|
45
|
-
lc = LexicalContext.new parent_context
|
46
|
-
set_args lc, arg_values
|
47
39
|
vm.instructions.push self.body
|
48
|
-
vm.contexts.push
|
40
|
+
vm.contexts.push set_args(parent_context, arg_values)
|
49
41
|
end
|
50
42
|
|
51
43
|
def setup_context context, names, values
|
@@ -63,7 +55,6 @@ module Nydp
|
|
63
55
|
ifn = Nydp::InterpretedFunction.new
|
64
56
|
ifn.arg_names = arg_list
|
65
57
|
ifn.extend Nydp::LexicalContextBuilder.select arg_list
|
66
|
-
ifn.initialize_names arg_list
|
67
58
|
ifn.body = compile_body body, cons(my_params, bindings), []
|
68
59
|
ifn
|
69
60
|
end
|
@@ -90,6 +81,11 @@ module Nydp
|
|
90
81
|
end
|
91
82
|
|
92
83
|
def execute vm
|
84
|
+
# TODO do not create a new Closure if this function does not refer to it
|
85
|
+
# - including top-level function definitions
|
86
|
+
# - and any other function that does not refer to any lexically-bound outer variable
|
87
|
+
# - for example (fn (x) (* x x)) in (map λx(* x x) things) does not need a closure, because
|
88
|
+
# the function does not refer to any lexical variable outside itself.
|
93
89
|
vm.push_arg Closure.new(self, vm.current_context)
|
94
90
|
end
|
95
91
|
|
data/lib/nydp/lexical_context.rb
CHANGED
@@ -38,14 +38,25 @@ module Nydp
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def to_s_with_indent str
|
41
|
-
me = @values.map { |k, v|
|
41
|
+
me = (@values || { }).map { |k, v|
|
42
42
|
[str, k, "=>", v].join ' '
|
43
43
|
}.join "\n"
|
44
44
|
me + (parent ? parent.to_s_with_indent(" #{str}") : '')
|
45
45
|
end
|
46
46
|
|
47
|
-
def
|
47
|
+
def pretty
|
48
48
|
to_s_with_indent ''
|
49
49
|
end
|
50
|
+
|
51
|
+
def to_s
|
52
|
+
values = []
|
53
|
+
n = 0
|
54
|
+
while at_index n
|
55
|
+
values << at_index(n).inspect
|
56
|
+
n += 1
|
57
|
+
end
|
58
|
+
parent_s = parent ? " parent #{parent.to_s}" : ""
|
59
|
+
"(context (#{values.join ' '})#{parent_s})"
|
60
|
+
end
|
50
61
|
end
|
51
62
|
end
|
@@ -1,12 +1,22 @@
|
|
1
1
|
module Nydp::LexicalContextBuilder
|
2
2
|
extend Nydp::Helper
|
3
3
|
|
4
|
+
def self.mklc nexpected
|
5
|
+
(nexpected > 0) ? "lc = Nydp::LexicalContext.new lc\n " : ""
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.build_arg_names ngiven
|
9
|
+
(["lc"] + (0...ngiven ).map { |i| "arg_#{i}"}).join ", "
|
10
|
+
end
|
11
|
+
|
4
12
|
def self.build_set_args_n_method ngiven, nexpected
|
5
13
|
setter_count = [ngiven, nexpected].min
|
6
|
-
arg_names = (0...ngiven ).map { |i| "arg_#{i}"}
|
7
14
|
setters = (0...setter_count).map { |i| "lc.at_#{i}= arg_#{i}"}
|
8
|
-
" def set_args_#{ngiven}
|
9
|
-
#{setters.join "\n "}
|
15
|
+
" def set_args_#{ngiven} #{build_arg_names ngiven}
|
16
|
+
#{mklc nexpected}#{setters.join "\n "}
|
17
|
+
lc
|
18
|
+
rescue StandardError => e
|
19
|
+
raise \"error in \#{self.class.name}#set_args_#{ngiven}\"
|
10
20
|
end
|
11
21
|
"
|
12
22
|
end
|
@@ -26,9 +36,12 @@ module Nydp::LexicalContextBuilder
|
|
26
36
|
if ngiven > setter_count
|
27
37
|
rest_setter = "lc.at_#{nexpected}= #{build_arg_conses arg_names[setter_count..-1], 0}"
|
28
38
|
end
|
29
|
-
" def set_args_#{ngiven}
|
30
|
-
#{setters.join "\n "}
|
39
|
+
" def set_args_#{ngiven} #{build_arg_names ngiven}
|
40
|
+
#{mklc 1}#{setters.join "\n "}
|
31
41
|
#{rest_setter}
|
42
|
+
lc
|
43
|
+
rescue StandardError => e
|
44
|
+
raise \"error in \#{self.class.name}#set_args_#{ngiven}\"
|
32
45
|
end
|
33
46
|
"
|
34
47
|
end
|
@@ -36,7 +49,10 @@ module Nydp::LexicalContextBuilder
|
|
36
49
|
def self.build_set_args_method nexpected
|
37
50
|
setters = (0...nexpected).map { |i| "lc.at_#{i}= args#{ ([".cdr"] * i).join }.car"}
|
38
51
|
" def set_args lc, args
|
39
|
-
#{setters.join "\n "}
|
52
|
+
#{mklc nexpected}#{setters.join "\n "}
|
53
|
+
lc
|
54
|
+
rescue StandardError => e
|
55
|
+
raise \"error in \#{self.class.name}#set_args\"
|
40
56
|
end
|
41
57
|
"
|
42
58
|
end
|
@@ -45,8 +61,11 @@ module Nydp::LexicalContextBuilder
|
|
45
61
|
setters = (0...nexpected).map { |i| "lc.at_#{i}= args#{ ([".cdr"] * i).join }.car"}
|
46
62
|
rest_set = "lc.at_#{nexpected}= args#{ ([".cdr"] *(nexpected)).join }"
|
47
63
|
" def set_args lc, args
|
48
|
-
#{setters.join "\n "}
|
64
|
+
#{mklc 1}#{setters.join "\n "}
|
49
65
|
#{rest_set}
|
66
|
+
lc
|
67
|
+
rescue StandardError => e
|
68
|
+
raise \"error in \#{self.class.name}#set_args\"
|
50
69
|
end
|
51
70
|
"
|
52
71
|
end
|
@@ -56,12 +75,10 @@ module Nydp::LexicalContextBuilder
|
|
56
75
|
existing = const_get(name) rescue nil
|
57
76
|
return name if existing
|
58
77
|
|
59
|
-
n_methods = (
|
78
|
+
n_methods = (0..3).map { |given| build_set_args_n_method given, expected_arg_count }
|
60
79
|
x_method = build_set_args_method expected_arg_count
|
61
80
|
klass = <<KLASS
|
62
81
|
module #{name}
|
63
|
-
def initialize_names names ; end
|
64
|
-
|
65
82
|
#{n_methods.join "\n"}
|
66
83
|
#{x_method}
|
67
84
|
end
|
@@ -76,12 +93,10 @@ KLASS
|
|
76
93
|
existing = const_get(name) rescue nil
|
77
94
|
return name if existing
|
78
95
|
|
79
|
-
n_methods = (
|
96
|
+
n_methods = (0..3).map { |given| build_set_args_n_rest_method given, proper_arg_count }
|
80
97
|
x_method = build_set_args_rest_method proper_arg_count
|
81
98
|
klass = <<KLASS
|
82
99
|
module #{name}
|
83
|
-
def initialize_names names ; end
|
84
|
-
|
85
100
|
#{n_methods.join "\n"}
|
86
101
|
#{x_method}
|
87
102
|
end
|