virtual_keywords 0.1.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|