virtual_keywords 0.1.0 → 0.3.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/lib/parsetree/History.txt +477 -0
- data/lib/parsetree/Manifest.txt +19 -0
- data/lib/parsetree/README.txt +97 -0
- data/lib/parsetree/Rakefile +37 -0
- data/lib/parsetree/bin/parse_tree_abc +89 -0
- data/lib/parsetree/bin/parse_tree_audit +28 -0
- data/lib/parsetree/bin/parse_tree_deps +62 -0
- data/lib/parsetree/bin/parse_tree_show +63 -0
- data/lib/parsetree/demo/printer.rb +20 -0
- data/lib/parsetree/lib/gauntlet_parsetree.rb +121 -0
- data/lib/parsetree/lib/parse_tree.rb +1202 -0
- data/lib/parsetree/lib/parse_tree_extensions.rb +59 -0
- data/lib/parsetree/lib/unified_ruby.rb +421 -0
- data/lib/parsetree/test/something.rb +53 -0
- data/lib/parsetree/test/test_parse_tree.rb +2567 -0
- data/lib/parsetree/test/test_parse_tree_extensions.rb +107 -0
- data/lib/parsetree/test/test_unified_ruby.rb +57 -0
- data/lib/parsetree/validate.sh +31 -0
- data/lib/sexps/{count_to_ten_sexp.txt → count_to_ten_sexp.rb} +0 -0
- data/lib/sexps/{sexps_and.txt → sexps_and.rb} +0 -0
- data/lib/sexps/{sexps_case_when.txt → sexps_case_when.rb} +0 -0
- data/lib/sexps/{sexps_greet.txt → sexps_greet.rb} +0 -0
- data/lib/sexps/sexps_not.rb +24 -0
- data/lib/sexps/{sexps_rewritten_keywords.txt → sexps_rewritten_keywords.rb} +0 -0
- data/lib/sexps/{sexps_symbolic_and.txt → sexps_symbolic_and.rb} +0 -0
- data/lib/sexps/sexps_until.rb +60 -0
- data/lib/sexps/{sexps_while.txt → sexps_while.rb} +0 -0
- data/lib/spec/class_reflection_spec.rb +64 -0
- data/lib/spec/keyword_rewriter_spec.rb +7 -54
- data/lib/spec/not_rewriter_spec.rb +25 -0
- data/lib/spec/parser_strategy_spec.rb +23 -0
- data/lib/spec/sexp_stringifier_spec.rb +19 -0
- data/lib/spec/spec_helper.rb +61 -307
- data/lib/spec/until_rewriter_spec.rb +26 -0
- data/lib/spec/virtualizees/and_user.rb +17 -0
- data/lib/spec/virtualizees/case_when_user.rb +20 -0
- data/lib/spec/virtualizees/fizzbuzzer.rb +15 -0
- data/lib/spec/virtualizees/greeter.rb +127 -0
- data/lib/spec/virtualizees/not_user.rb +9 -0
- data/lib/spec/virtualizees/operator_user.rb +15 -0
- data/lib/spec/virtualizees/or_user.rb +17 -0
- data/lib/spec/virtualizees/parents.rb +8 -0
- data/lib/spec/virtualizees/until_user.rb +16 -0
- data/lib/spec/virtualizees/while_user.rb +16 -0
- data/lib/spec/virtualizer_spec.rb +46 -83
- data/lib/virtual_keywords/class_reflection.rb +88 -0
- data/lib/virtual_keywords/deep_copy_array.rb +12 -0
- data/lib/virtual_keywords/keyword_rewriter.rb +54 -0
- data/lib/virtual_keywords/parser_strategy.rb +40 -0
- data/lib/virtual_keywords/rewritten_keywords.rb +15 -0
- data/lib/virtual_keywords/sexp_stringifier.rb +1 -5
- data/lib/virtual_keywords/version.rb +1 -1
- data/lib/virtual_keywords/virtualizer.rb +30 -115
- data/lib/virtual_keywords.rb +31 -5
- metadata +117 -90
- data/lib/spec/class_mirrorer_spec.rb +0 -18
- data/lib/virtual_keywords/class_mirrorer.rb +0 -39
@@ -0,0 +1,59 @@
|
|
1
|
+
class Method
|
2
|
+
def with_class_and_method_name
|
3
|
+
if self.inspect =~ /<Method: (.*)\#(.*)>/ then
|
4
|
+
klass = eval $1
|
5
|
+
method = $2.intern
|
6
|
+
raise "Couldn't determine class from #{self.inspect}" if klass.nil?
|
7
|
+
return yield(klass, method)
|
8
|
+
else
|
9
|
+
raise "Can't parse signature: #{self.inspect}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_sexp
|
14
|
+
require 'parse_tree'
|
15
|
+
require 'unified_ruby'
|
16
|
+
parser = ParseTree.new(false)
|
17
|
+
unifier = Unifier.new
|
18
|
+
with_class_and_method_name do |klass, method|
|
19
|
+
old_sexp = parser.parse_tree_for_method(klass, method)
|
20
|
+
unifier.process(old_sexp)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_ruby
|
25
|
+
sexp = self.to_sexp
|
26
|
+
Ruby2Ruby.new.process sexp
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class ProcStoreTmp
|
31
|
+
@@n = 0
|
32
|
+
def self.new_name
|
33
|
+
@@n += 1
|
34
|
+
return :"myproc#{@@n}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class UnboundMethod
|
39
|
+
def to_ruby
|
40
|
+
name = ProcStoreTmp.new_name
|
41
|
+
ProcStoreTmp.send(:define_method, name, self)
|
42
|
+
m = ProcStoreTmp.new.method(name)
|
43
|
+
result = m.to_ruby.sub(/def #{name}(?:\(([^\)]*)\))?/,
|
44
|
+
'proc { |\1|').sub(/end\Z/, '}')
|
45
|
+
return result
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class Proc
|
50
|
+
def to_sexp
|
51
|
+
pt = ParseTree.new(false)
|
52
|
+
sexp = pt.parse_tree_for_proc(self)
|
53
|
+
Unifier.new.process(sexp)
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_ruby
|
57
|
+
Ruby2Ruby.new.process(self.to_sexp).sub(/^\Aproc do/, 'proc {').sub(/end\Z/, '}')
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,421 @@
|
|
1
|
+
require 'sexp_processor'
|
2
|
+
require 'composite_sexp_processor'
|
3
|
+
|
4
|
+
$TESTING ||= false
|
5
|
+
|
6
|
+
module UnifiedRuby
|
7
|
+
def process exp
|
8
|
+
exp = Sexp.from_array exp unless Sexp === exp or exp.nil?
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def rewrite_argscat exp
|
13
|
+
_, ary, val = exp
|
14
|
+
ary = s(:array, ary) unless ary.first == :array
|
15
|
+
ary << s(:splat, val)
|
16
|
+
end
|
17
|
+
|
18
|
+
def rewrite_argspush exp
|
19
|
+
exp[0] = :arglist
|
20
|
+
exp
|
21
|
+
end
|
22
|
+
|
23
|
+
def rewrite_attrasgn(exp)
|
24
|
+
last = exp.last
|
25
|
+
|
26
|
+
if Sexp === last then
|
27
|
+
last[0] = :arglist if last[0] == :array
|
28
|
+
else
|
29
|
+
exp << s(:arglist)
|
30
|
+
end
|
31
|
+
|
32
|
+
exp
|
33
|
+
end
|
34
|
+
|
35
|
+
def rewrite_begin(exp)
|
36
|
+
raise "wtf: #{exp.inspect}" if exp.size > 2
|
37
|
+
exp.last
|
38
|
+
end
|
39
|
+
|
40
|
+
def rewrite_block_pass exp
|
41
|
+
case exp.size
|
42
|
+
when 2 then
|
43
|
+
_, block = exp
|
44
|
+
case block.first
|
45
|
+
when :lasgn then
|
46
|
+
block[-1] = :"&#{block[-1]}"
|
47
|
+
exp = block
|
48
|
+
else
|
49
|
+
raise "huh?: #{block.inspect}"
|
50
|
+
end
|
51
|
+
when 3 then
|
52
|
+
_, block, recv = exp
|
53
|
+
case recv.first
|
54
|
+
when :super then
|
55
|
+
recv << s(:block_pass, block)
|
56
|
+
exp = recv
|
57
|
+
when :call then
|
58
|
+
recv.last << s(:block_pass, block)
|
59
|
+
exp = recv
|
60
|
+
when :masgn then
|
61
|
+
block[-1] = :"&#{block[-1]}"
|
62
|
+
recv.last << block
|
63
|
+
exp = recv
|
64
|
+
else
|
65
|
+
raise "huh?: #{recv.inspect}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
exp
|
70
|
+
end
|
71
|
+
|
72
|
+
def rewrite_bmethod(exp)
|
73
|
+
_, args, body = exp
|
74
|
+
|
75
|
+
args ||= s(:array)
|
76
|
+
body ||= s(:block)
|
77
|
+
|
78
|
+
args = s(:args, args) unless args[0] == :array
|
79
|
+
|
80
|
+
args = args[1] if args[1] && args[1][0] == :masgn # TODO: clean up
|
81
|
+
args = args[1] if args[1] && args[1][0] == :array
|
82
|
+
args[0] = :args
|
83
|
+
|
84
|
+
# this is ugly because rewriters are depth first.
|
85
|
+
# TODO: maybe we could come up with some way to do both forms of rewriting.
|
86
|
+
args.map! { |s|
|
87
|
+
if Sexp === s
|
88
|
+
case s[0]
|
89
|
+
when :lasgn then
|
90
|
+
s[1]
|
91
|
+
when :splat then
|
92
|
+
:"*#{s[1][1]}"
|
93
|
+
else
|
94
|
+
raise "huh?: #{s.inspect}"
|
95
|
+
end
|
96
|
+
else
|
97
|
+
s
|
98
|
+
end
|
99
|
+
}
|
100
|
+
|
101
|
+
body = s(:block, body) unless body[0] == :block
|
102
|
+
body.insert 1, args
|
103
|
+
|
104
|
+
s(:scope, body)
|
105
|
+
end
|
106
|
+
|
107
|
+
def rewrite_iter(exp)
|
108
|
+
t, recv, args, body = exp
|
109
|
+
|
110
|
+
# unwrap masgn args if there is only 1 thing to assign and it isn't splat
|
111
|
+
if Sexp === args and args.sexp_type == :masgn and args.array.size == 2 then
|
112
|
+
if args.array.last.sexp_type != :splat then
|
113
|
+
args = args.array.last
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
r = s(t, recv, args, body)
|
118
|
+
r.delete_at 3 unless body # HACK omg this sucks
|
119
|
+
r
|
120
|
+
end
|
121
|
+
|
122
|
+
def rewrite_call(exp)
|
123
|
+
args = exp.last
|
124
|
+
case args
|
125
|
+
when nil
|
126
|
+
exp.pop
|
127
|
+
when Array
|
128
|
+
case args.first
|
129
|
+
when :array, :arglist then
|
130
|
+
args[0] = :arglist
|
131
|
+
when :argscat, :splat then
|
132
|
+
exp[-1] = s(:arglist, args)
|
133
|
+
else
|
134
|
+
raise "unknown type in call #{args.first.inspect} in #{exp.inspect}"
|
135
|
+
end
|
136
|
+
return exp
|
137
|
+
end
|
138
|
+
|
139
|
+
exp << s(:arglist)
|
140
|
+
|
141
|
+
exp
|
142
|
+
end
|
143
|
+
|
144
|
+
def rewrite_dasgn(exp)
|
145
|
+
exp[0] = :lasgn
|
146
|
+
exp
|
147
|
+
end
|
148
|
+
|
149
|
+
alias :rewrite_dasgn_curr :rewrite_dasgn
|
150
|
+
|
151
|
+
##
|
152
|
+
# :defn is one of the most complex of all the ASTs in ruby. We do
|
153
|
+
# one of 3 different translations:
|
154
|
+
#
|
155
|
+
# 1) From:
|
156
|
+
#
|
157
|
+
# s(:defn, :name, s(:scope, s(:block, s(:args, ...), ...)))
|
158
|
+
# s(:defn, :name, s(:bmethod, s(:masgn, s(:dasgn_curr, :args)), s(:block, ...)))
|
159
|
+
# s(:defn, :name, s(:fbody, s(:bmethod, s(:masgn, s(:dasgn_curr, :splat)), s(:block, ...))))
|
160
|
+
#
|
161
|
+
# to:
|
162
|
+
#
|
163
|
+
# s(:defn, :name, s(:args, ...), s(:scope, s:(block, ...)))
|
164
|
+
#
|
165
|
+
# 2) From:
|
166
|
+
#
|
167
|
+
# s(:defn, :writer=, s(:attrset, :@name))
|
168
|
+
#
|
169
|
+
# to:
|
170
|
+
#
|
171
|
+
# s(:defn, :writer=, s(:args), s(:attrset, :@name))
|
172
|
+
#
|
173
|
+
# 3) From:
|
174
|
+
#
|
175
|
+
# s(:defn, :reader, s(:ivar, :@name))
|
176
|
+
#
|
177
|
+
# to:
|
178
|
+
#
|
179
|
+
# s(:defn, :reader, s(:args), s(:ivar, :@name))
|
180
|
+
#
|
181
|
+
|
182
|
+
def rewrite_defn(exp)
|
183
|
+
weirdo = exp.ivar || exp.attrset
|
184
|
+
fbody = exp.fbody(true)
|
185
|
+
|
186
|
+
weirdo ||= fbody.cfunc if fbody
|
187
|
+
|
188
|
+
exp.push(fbody.scope) if fbody unless weirdo
|
189
|
+
|
190
|
+
args = exp.scope.block.args(true) unless weirdo if exp.scope
|
191
|
+
exp.insert 2, args if args
|
192
|
+
|
193
|
+
# move block_arg up and in
|
194
|
+
block_arg = exp.scope.block.block_arg(true) rescue nil
|
195
|
+
if block_arg
|
196
|
+
block = args.block(true)
|
197
|
+
args << :"&#{block_arg.last}"
|
198
|
+
args << block if block
|
199
|
+
end
|
200
|
+
|
201
|
+
# patch up attr_accessor methods
|
202
|
+
if weirdo then
|
203
|
+
case
|
204
|
+
when fbody && fbody.cfunc then
|
205
|
+
exp.insert 2, s(:args, :"*args")
|
206
|
+
when exp.ivar then
|
207
|
+
exp.insert 2, s(:args)
|
208
|
+
when exp.attrset then
|
209
|
+
exp.insert 2, s(:args, :arg)
|
210
|
+
else
|
211
|
+
raise "unknown wierdo: #{wierdo.inpsect}"
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
exp
|
216
|
+
end
|
217
|
+
|
218
|
+
def rewrite_defs(exp)
|
219
|
+
receiver = exp.delete_at 1
|
220
|
+
|
221
|
+
# TODO: I think this would be better as rewrite_scope, but that breaks others
|
222
|
+
exp = s(exp.shift, exp.shift,
|
223
|
+
s(:scope,
|
224
|
+
s(:block, exp.scope.args))) if exp.scope && exp.scope.args
|
225
|
+
|
226
|
+
result = rewrite_defn(exp)
|
227
|
+
result.insert 1, receiver
|
228
|
+
|
229
|
+
result
|
230
|
+
end
|
231
|
+
|
232
|
+
def rewrite_dmethod(exp)
|
233
|
+
exp.shift # type
|
234
|
+
exp.shift # dmethod name
|
235
|
+
exp.shift # scope / block / body
|
236
|
+
end
|
237
|
+
|
238
|
+
def rewrite_dvar(exp)
|
239
|
+
exp[0] = :lvar
|
240
|
+
exp
|
241
|
+
end
|
242
|
+
|
243
|
+
def rewrite_fcall(exp)
|
244
|
+
exp[0] = :call
|
245
|
+
exp.insert 1, nil
|
246
|
+
|
247
|
+
rewrite_call(exp)
|
248
|
+
end
|
249
|
+
|
250
|
+
def rewrite_flip2(exp)
|
251
|
+
# from:
|
252
|
+
# s(:flip2,
|
253
|
+
# s(:call, s(:lit, 1), :==, s(:arglist, s(:gvar, :$.))),
|
254
|
+
# s(:call, s(:lit, 2), :a?, s(:arglist, s(:call, nil, :b, s(:arglist)))))
|
255
|
+
# to:
|
256
|
+
# s(:flip2,
|
257
|
+
# s(:lit, 1),
|
258
|
+
# s(:call, s(:lit, 2), :a?, s(:arglist, s(:call, nil, :b, s(:arglist)))))
|
259
|
+
exp[1] = exp[1][1] if exp[1][0] == :call && exp[1][1][0] == :lit
|
260
|
+
exp
|
261
|
+
end
|
262
|
+
|
263
|
+
alias :rewrite_flip3 :rewrite_flip2
|
264
|
+
|
265
|
+
def rewrite_masgn(exp)
|
266
|
+
t, lhs, lhs_splat, rhs = exp
|
267
|
+
|
268
|
+
lhs ||= s(:array)
|
269
|
+
|
270
|
+
if lhs_splat then
|
271
|
+
case lhs_splat.first
|
272
|
+
when :array then
|
273
|
+
lhs_splat = lhs_splat.last if lhs_splat.last.first == :splat
|
274
|
+
when :splat then
|
275
|
+
# do nothing
|
276
|
+
else
|
277
|
+
lhs_splat = s(:splat, lhs_splat)
|
278
|
+
end
|
279
|
+
lhs << lhs_splat
|
280
|
+
end
|
281
|
+
|
282
|
+
# unwrap RHS from array IF it is only a splat node
|
283
|
+
rhs = rhs.last if rhs && # TODO: rhs.structure =~ s(:array, s(:splat))
|
284
|
+
rhs.size == 2 && rhs.structure.flatten.first(2) == [:array, :splat]
|
285
|
+
|
286
|
+
s(t, lhs, rhs).compact
|
287
|
+
end
|
288
|
+
|
289
|
+
def rewrite_op_asgn1(exp)
|
290
|
+
exp[2][0] = :arglist # if exp[2][0] == :array
|
291
|
+
exp
|
292
|
+
end
|
293
|
+
|
294
|
+
def rewrite_resbody(exp)
|
295
|
+
exp[1] ||= s(:array) # no args
|
296
|
+
|
297
|
+
body = exp[2]
|
298
|
+
if body then
|
299
|
+
case body.first
|
300
|
+
when :lasgn, :iasgn then
|
301
|
+
exp[1] << exp.delete_at(2) if body[-1] == s(:gvar, :$!)
|
302
|
+
when :block then
|
303
|
+
exp[1] << body.delete_at(1) if [:lasgn, :iasgn].include?(body[1][0]) &&
|
304
|
+
body[1][-1] == s(:gvar, :$!)
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
exp << nil if exp.size == 2 # no body
|
309
|
+
|
310
|
+
exp
|
311
|
+
end
|
312
|
+
|
313
|
+
def rewrite_rescue(exp)
|
314
|
+
# SKETCHY HACK return exp if exp.size > 4
|
315
|
+
ignored = exp.shift
|
316
|
+
body = exp.shift unless exp.first.first == :resbody
|
317
|
+
resbody = exp.shift
|
318
|
+
els = exp.shift unless exp.first.first == :resbody unless exp.empty?
|
319
|
+
rest = exp.empty? ? nil : exp # graceful re-rewriting (see rewrite_begin)
|
320
|
+
|
321
|
+
resbodies = []
|
322
|
+
|
323
|
+
unless rest then
|
324
|
+
while resbody do
|
325
|
+
resbodies << resbody
|
326
|
+
resbody = resbody.resbody(true)
|
327
|
+
end
|
328
|
+
|
329
|
+
resbodies.each do |resbody|
|
330
|
+
if resbody[2] && resbody[2][0] == :block && resbody[2].size == 2 then
|
331
|
+
resbody[2] = resbody[2][-1]
|
332
|
+
end
|
333
|
+
end
|
334
|
+
else
|
335
|
+
resbodies = [resbody] + rest
|
336
|
+
end
|
337
|
+
|
338
|
+
resbodies << els if els
|
339
|
+
|
340
|
+
s(:rescue, body, *resbodies).compact
|
341
|
+
end
|
342
|
+
|
343
|
+
def rewrite_splat(exp)
|
344
|
+
good = [:arglist, :argspush, :array, :svalue, :yield, :super].include? context.first
|
345
|
+
exp = s(:array, exp) unless good
|
346
|
+
exp
|
347
|
+
end
|
348
|
+
|
349
|
+
def rewrite_super(exp)
|
350
|
+
return exp if exp.structure.flatten.first(3) == [:super, :array, :splat]
|
351
|
+
exp.push(*exp.pop[1..-1]) if exp.size == 2 && exp.last.first == :array
|
352
|
+
exp
|
353
|
+
end
|
354
|
+
|
355
|
+
def rewrite_vcall(exp)
|
356
|
+
exp.push nil
|
357
|
+
rewrite_fcall(exp)
|
358
|
+
end
|
359
|
+
|
360
|
+
def rewrite_yield(exp)
|
361
|
+
real_array = exp.pop if exp.size == 3
|
362
|
+
|
363
|
+
if exp.size == 2 then
|
364
|
+
if real_array then
|
365
|
+
exp[-1] = s(:array, exp[-1]) if exp[-1][0] != :array
|
366
|
+
else
|
367
|
+
exp.push(*exp.pop[1..-1]) if exp.last.first == :array
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
exp
|
372
|
+
end
|
373
|
+
|
374
|
+
def rewrite_zarray(exp)
|
375
|
+
exp[0] = :array
|
376
|
+
exp
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
class PreUnifier < SexpProcessor
|
381
|
+
def initialize
|
382
|
+
super
|
383
|
+
@unsupported.delete :newline
|
384
|
+
end
|
385
|
+
|
386
|
+
def rewrite_call exp
|
387
|
+
exp << s(:arglist) if exp.size < 4
|
388
|
+
exp.last[0] = :arglist if exp.last.first == :array
|
389
|
+
exp
|
390
|
+
end
|
391
|
+
|
392
|
+
def rewrite_fcall exp
|
393
|
+
exp << s(:arglist) if exp.size < 3
|
394
|
+
if exp[-1][0] == :array then
|
395
|
+
has_splat = exp[-1].find { |s| Array === s && s.first == :splat }
|
396
|
+
exp[-1] = s(:arglist, exp[-1]) if has_splat
|
397
|
+
exp[-1][0] = :arglist
|
398
|
+
end
|
399
|
+
exp
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
class PostUnifier < SexpProcessor
|
404
|
+
include UnifiedRuby
|
405
|
+
|
406
|
+
def initialize
|
407
|
+
super
|
408
|
+
@unsupported.delete :newline
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
##
|
413
|
+
# Quick and easy SexpProcessor that unified the sexp structure.
|
414
|
+
|
415
|
+
class Unifier < CompositeSexpProcessor
|
416
|
+
def initialize
|
417
|
+
super
|
418
|
+
self << PreUnifier.new
|
419
|
+
self << PostUnifier.new
|
420
|
+
end
|
421
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
|
2
|
+
class Something
|
3
|
+
|
4
|
+
def self.classmethod
|
5
|
+
1 + 1
|
6
|
+
end
|
7
|
+
|
8
|
+
# Other edge cases:
|
9
|
+
|
10
|
+
def opt_args(arg1, arg2 = 42, *args)
|
11
|
+
arg3 = arg1 * arg2 * 7
|
12
|
+
puts(arg3.to_s)
|
13
|
+
return "foo"
|
14
|
+
end
|
15
|
+
|
16
|
+
def multi_args(arg1, arg2)
|
17
|
+
arg3 = arg1 * arg2 * 7
|
18
|
+
puts(arg3.to_s)
|
19
|
+
return "foo"
|
20
|
+
end
|
21
|
+
|
22
|
+
def unknown_args(arg1, arg2)
|
23
|
+
# does nothing
|
24
|
+
return arg1
|
25
|
+
end
|
26
|
+
|
27
|
+
def determine_args
|
28
|
+
5 == unknown_args(4, "known")
|
29
|
+
end
|
30
|
+
|
31
|
+
# TODO: sort list
|
32
|
+
def bbegin
|
33
|
+
begin
|
34
|
+
1
|
35
|
+
rescue SyntaxError => e1
|
36
|
+
2
|
37
|
+
rescue Exception => e2
|
38
|
+
3
|
39
|
+
else
|
40
|
+
4
|
41
|
+
ensure
|
42
|
+
5
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def bbegin_no_exception
|
47
|
+
begin
|
48
|
+
5
|
49
|
+
rescue
|
50
|
+
6
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|