mvz-live_ast 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.rdoc +14 -0
  3. data/Rakefile +48 -9
  4. data/devel/levitate.rb +5 -674
  5. data/lib/live_ast/common.rb +22 -21
  6. data/lib/live_ast/error.rb +2 -2
  7. data/lib/live_ast/irb_spy.rb +4 -6
  8. data/lib/live_ast/linker.rb +7 -7
  9. data/lib/live_ast/loader.rb +6 -6
  10. data/lib/live_ast/reader.rb +2 -2
  11. data/lib/live_ast/replace_eval.rb +27 -31
  12. data/lib/live_ast/replace_load.rb +1 -1
  13. data/lib/live_ast/ruby_parser.rb +24 -22
  14. data/lib/live_ast/ruby_parser/test.rb +183 -179
  15. data/lib/live_ast/ruby_parser/unparser.rb +10 -6
  16. data/lib/live_ast/to_ast.rb +1 -1
  17. data/lib/live_ast/version.rb +1 -1
  18. data/test/ast_eval/ast_eval_test.rb +11 -0
  19. data/test/ast_load/ast_load_test.rb +45 -0
  20. data/test/backtrace_test.rb +29 -28
  21. data/test/{noninvasive_test.rb → base/noninvasive_test.rb} +7 -5
  22. data/test/base/reload_test.rb +41 -0
  23. data/test/covert_define_method_test.rb +1 -1
  24. data/test/define_method_test.rb +5 -5
  25. data/test/encoding_test.rb +5 -5
  26. data/test/error_test.rb +6 -6
  27. data/test/eval_test.rb +7 -7
  28. data/test/flush_cache_test.rb +6 -6
  29. data/test/full/ast_reload_test.rb +39 -0
  30. data/test/{replace_eval_test.rb → full/replace_eval_test.rb} +31 -12
  31. data/test/irb_test.rb +1 -1
  32. data/test/lambda_test.rb +7 -0
  33. data/test/load_path_test.rb +12 -12
  34. data/test/load_test.rb +35 -35
  35. data/test/main.rb +19 -27
  36. data/test/nested_test.rb +1 -1
  37. data/test/readme_test.rb +1 -3
  38. data/test/recursive_eval_test.rb +2 -3
  39. data/test/redefine_method_test.rb +2 -2
  40. data/test/rubygems_test.rb +1 -1
  41. data/test/rubyspec_test.rb +3 -3
  42. data/test/stdlib_test.rb +1 -1
  43. data/test/thread_test.rb +1 -2
  44. data/test/to_ast/to_ast_feature_test.rb +11 -0
  45. data/test/to_ruby/to_ruby_feature_test.rb +11 -0
  46. data/test/{to_ruby_test.rb → to_ruby/to_ruby_test.rb} +2 -2
  47. metadata +93 -91
  48. data/test/ast_eval_feature_test.rb +0 -11
  49. data/test/ast_load_feature_test.rb +0 -11
  50. data/test/reload_test.rb +0 -105
  51. data/test/to_ast_feature_test.rb +0 -15
  52. data/test/to_ruby_feature_test.rb +0 -15
@@ -2,36 +2,37 @@
2
2
  module LiveAST
3
3
  module Common
4
4
  module_function
5
-
5
+
6
6
  def arg_to_str(arg)
7
- begin
8
- arg.to_str
9
- rescue NameError
10
- thing = if arg.nil? then nil else arg.class end
11
-
12
- raise TypeError,
13
- RUBY_VERSION < "2.0.0" ?
14
- "can't convert #{thing.inspect} into String" :
15
- "no implicit conversion of #{thing.inspect} into String"
16
- end
7
+ arg.to_str
8
+ rescue NameError
9
+ thing = arg.nil? ? nil : arg.class
10
+
11
+ message = if RUBY_VERSION < "2.0.0"
12
+ "can't convert #{thing.inspect} into String"
13
+ else
14
+ "no implicit conversion of #{thing.inspect} into String"
15
+ end
16
+ raise TypeError, message
17
17
  end
18
18
 
19
19
  def check_arity(args, range)
20
- unless range.include? args.size
21
- range = 0 if range == (0..0)
20
+ return if range.include? args.size
22
21
 
23
- raise ArgumentError,
22
+ range = 0 if range == (0..0)
23
+
24
+ raise ArgumentError,
24
25
  "wrong number of arguments (#{args.size} for #{range})"
25
- end
26
26
  end
27
27
 
28
28
  def check_is_binding(obj)
29
- unless obj.is_a? Binding
30
- raise TypeError,
31
- RUBY_VERSION < "2.1.0" ?
32
- "wrong argument type #{obj.class} (expected Binding)" :
33
- "wrong argument type #{obj.class} (expected binding)"
34
- end
29
+ return if obj.is_a? Binding
30
+ message = if RUBY_VERSION < "2.1.0"
31
+ "wrong argument type #{obj.class} (expected Binding)"
32
+ else
33
+ "wrong argument type #{obj.class} (expected binding)"
34
+ end
35
+ raise TypeError, message
35
36
  end
36
37
 
37
38
  def location_for_eval(*args)
@@ -1,8 +1,8 @@
1
1
  module LiveAST
2
2
  class MultipleDefinitionsOnSameLineError < ScriptError
3
3
  def message
4
- "AST requested for a method or block that shares a line " <<
5
- "with another method or block."
4
+ "AST requested for a method or block that shares a line " \
5
+ "with another method or block."
6
6
  end
7
7
  end
8
8
 
@@ -9,7 +9,7 @@ module LiveAST
9
9
  def code_at(line)
10
10
  unless @history
11
11
  raise NotImplementedError,
12
- "LiveAST cannot access history for this IRB input method"
12
+ "LiveAST cannot access history for this IRB input method"
13
13
  end
14
14
  grow = 0
15
15
  begin
@@ -27,16 +27,14 @@ module LiveAST
27
27
  end
28
28
 
29
29
  [
30
- defined?(IRB::StdioInputMethod) ? IRB::StdioInputMethod : nil,
31
- defined?(IRB::ReadlineInputMethod) ? IRB::ReadlineInputMethod : nil,
30
+ defined?(IRB::StdioInputMethod) ? IRB::StdioInputMethod : nil,
31
+ defined?(IRB::ReadlineInputMethod) ? IRB::ReadlineInputMethod : nil,
32
32
  ].compact.each do |klass|
33
33
  klass.module_eval do
34
34
  alias_method :live_ast_original_gets, :gets
35
35
  def gets
36
36
  live_ast_original_gets.tap do
37
- if defined?(@line)
38
- LiveAST::IRBSpy.history = @line
39
- end
37
+ LiveAST::IRBSpy.history = @line if defined?(@line)
40
38
  end
41
39
  end
42
40
  end
@@ -15,31 +15,31 @@ module LiveAST
15
15
 
16
16
  module Attacher
17
17
  VAR_NAME = :@_live_ast
18
-
18
+
19
19
  def attach_to_proc(obj, ast)
20
20
  obj.instance_variable_set(VAR_NAME, ast)
21
21
  end
22
-
22
+
23
23
  def fetch_proc_attachment(obj)
24
24
  if obj.instance_variable_defined?(VAR_NAME)
25
25
  obj.instance_variable_get(VAR_NAME)
26
26
  end
27
27
  end
28
-
28
+
29
29
  def attach_to_method(klass, method, ast)
30
30
  unless klass.instance_variable_defined?(VAR_NAME)
31
31
  klass.instance_variable_set(VAR_NAME, {})
32
32
  end
33
33
  klass.instance_variable_get(VAR_NAME)[method] = ast
34
34
  end
35
-
35
+
36
36
  def fetch_method_attachment(klass, method)
37
37
  if klass.instance_variable_defined?(VAR_NAME)
38
38
  klass.instance_variable_get(VAR_NAME)[method]
39
39
  end
40
40
  end
41
41
  end
42
-
42
+
43
43
  module Linker
44
44
  REVISION_TOKEN = "|ast@"
45
45
 
@@ -80,9 +80,9 @@ module LiveAST
80
80
 
81
81
  def fetch_from_cache(file, line)
82
82
  cache = @caches[file]
83
- if !cache and !file.index(REVISION_TOKEN)
83
+ if !cache && !file.index(REVISION_TOKEN)
84
84
  _, cache =
85
- if defined?(IRB) and file == "(irb)"
85
+ if defined?(IRB) && file == "(irb)"
86
86
  new_cache(IRBSpy.code_at(line), file, line, false)
87
87
  else
88
88
  #
@@ -6,29 +6,29 @@ module LiveAST
6
6
 
7
7
  # guards to protect toplevel locals
8
8
  header, footer, warnings_ok = header_footer(wrap)
9
-
9
+
10
10
  parser_src = Reader.read(file)
11
11
  evaler_src = header << parser_src << footer
12
-
12
+
13
13
  run = lambda do
14
14
  Evaler.eval(parser_src, evaler_src, TOPLEVEL_BINDING, file, 1)
15
15
  end
16
16
  warnings_ok ? run.call : suppress_warnings(&run)
17
17
  true
18
18
  end
19
-
19
+
20
20
  def header_footer(wrap)
21
21
  if wrap
22
22
  return "class << Object.new;", ";end", true
23
23
  else
24
24
  locals = NATIVE_EVAL.call("local_variables", TOPLEVEL_BINDING)
25
-
25
+
26
26
  params = locals.empty? ? "" : ("|;" + locals.join(",") + "|")
27
-
27
+
28
28
  return "lambda do #{params}", ";end.call", locals.empty?
29
29
  end
30
30
  end
31
-
31
+
32
32
  def suppress_warnings
33
33
  previous = $VERBOSE
34
34
  $VERBOSE = nil
@@ -5,8 +5,8 @@ module LiveAST
5
5
  MAGIC_COMMENT = /\A(?:#!.*?\n)?\s*\#.*(?:en)?coding\s*[:=]\s*([^\s;]+)/
6
6
 
7
7
  def self.read(file)
8
- contents = File.read(file, :encoding => "BINARY")
9
-
8
+ contents = File.read(file, encoding: "BINARY")
9
+
10
10
  utf8 = contents.sub!(UTF8_BOM, "") ? "UTF-8" : nil
11
11
 
12
12
  # magic comment overrides BOM
@@ -29,51 +29,47 @@ module LiveAST
29
29
  Thread.current[:_live_ast_arg_cache] ||= {}
30
30
  end
31
31
 
32
+ private
33
+
32
34
  def handle_args(args)
33
35
  if RUBY_VERSION < '2.0.0'
34
- if args.empty?
35
- raise ArgumentError, "block not supplied"
36
- end
36
+ handle_args_pre_20(args)
37
+ else
38
+ handle_args_20(args)
39
+ end
40
+ end
37
41
 
38
- args[0] = Common.arg_to_str(args[0])
42
+ def handle_args_20(args)
43
+ LiveAST::Common.check_arity(args, 1..3)
44
+ args[0] = Common.arg_to_str(args[0])
45
+ args[1] = Common.arg_to_str(args[1]) if args.length > 1
46
+ end
39
47
 
40
- unless (1..3).include? args.size
41
- raise ArgumentError,
42
- "wrong number of arguments: instance_eval(src) or instance_eval{..}"
43
- end
44
- else
45
- LiveAST::Common.check_arity(args, 1..3)
46
- args[0] = Common.arg_to_str(args[0])
48
+ def handle_args_pre_20(args)
49
+ raise ArgumentError, "block not supplied" if args.empty?
50
+
51
+ args[0] = Common.arg_to_str(args[0])
52
+
53
+ unless (1..3).include? args.size
54
+ raise ArgumentError,
55
+ "wrong number of arguments: instance_eval(src) or instance_eval{..}"
47
56
  end
48
-
49
- args[1] = Common.arg_to_str(args[1]) if args[1]
57
+
58
+ args[1] = Common.arg_to_str(args[1]) if args.length > 1
50
59
  end
51
60
  end
52
61
  end
53
-
62
+
54
63
  # ensure the parser is loaded -- rubygems calls eval
55
64
  parser
56
65
  end
57
66
 
58
- # squelch alias warnings
59
- prev_verbose = $VERBOSE
60
- $VERBOSE = nil
61
-
67
+ # Override for Kernel#eval and Kernel.eval
62
68
  module Kernel
63
69
  class << self
64
70
  alias_method :live_ast_original_singleton_eval, :eval
65
-
66
- def eval(*args)
67
- LiveAST::Common.check_arity(args, 1..4)
68
- LiveAST.eval(
69
- "::Kernel.live_ast_original_instance_eval do;" << args[0] << ";end",
70
- args[1] || binding.of_caller(1),
71
- *LiveAST::Common.location_for_eval(*args[1..3]))
72
- end
73
71
  end
74
72
 
75
- private
76
-
77
73
  alias_method :live_ast_original_eval, :eval
78
74
 
79
75
  def eval(*args)
@@ -85,6 +81,7 @@ module Kernel
85
81
  end
86
82
  end
87
83
 
84
+ # Override for Binding#eval
88
85
  class Binding
89
86
  alias_method :live_ast_original_binding_eval, :eval
90
87
 
@@ -93,6 +90,7 @@ class Binding
93
90
  end
94
91
  end
95
92
 
93
+ # Override for BasicObject#instance_eval
96
94
  class BasicObject
97
95
  alias_method :live_ast_original_instance_eval, :instance_eval
98
96
 
@@ -106,6 +104,7 @@ class BasicObject
106
104
  end
107
105
  end
108
106
 
107
+ # Overrides for Module#module_eval and Module#class_eval
109
108
  class Module
110
109
  alias_method :live_ast_original_module_eval, :module_eval
111
110
 
@@ -121,6 +120,3 @@ class Module
121
120
  remove_method :class_eval
122
121
  alias_method :class_eval, :module_eval
123
122
  end
124
-
125
- # unsquelch alias warnings
126
- $VERBOSE = prev_verbose
@@ -6,7 +6,7 @@ module Kernel
6
6
  def load(file, wrap = false)
7
7
  LiveAST.load(file, wrap)
8
8
  end
9
-
9
+
10
10
  class << self
11
11
  remove_method :load
12
12
  end
@@ -1,32 +1,34 @@
1
1
  require 'ruby_parser'
2
2
  require 'live_ast/base'
3
3
 
4
- class LiveAST::RubyParser
5
- #
6
- # Returns a line-to-sexp hash where sexp corresponds to the method
7
- # or block defined at the given line.
8
- #
9
- # This method is the only requirement of a LiveAST parser plugin.
10
- #
11
- def parse(source)
12
- @defs = {}
13
- process RubyParser.new.parse(source)
14
- @defs
15
- end
16
-
17
- def process(sexp)
18
- case sexp.first
19
- when :defn, :defs, :iter
20
- store_sexp(sexp, sexp.line)
4
+ module LiveAST
5
+ class RubyParser
6
+ #
7
+ # Returns a line-to-sexp hash where sexp corresponds to the method
8
+ # or block defined at the given line.
9
+ #
10
+ # This method is the only requirement of a LiveAST parser plugin.
11
+ #
12
+ def parse(source)
13
+ @defs = {}
14
+ process ::RubyParser.new.parse(source)
15
+ @defs
21
16
  end
22
17
 
23
- sexp.each do |elem|
24
- process(elem) if elem.is_a? Sexp
18
+ def process(sexp)
19
+ case sexp.first
20
+ when :defn, :defs, :iter
21
+ store_sexp(sexp, sexp.line)
22
+ end
23
+
24
+ sexp.each do |elem|
25
+ process(elem) if elem.is_a? Sexp
26
+ end
25
27
  end
26
- end
27
28
 
28
- def store_sexp(sexp, line)
29
- @defs[line] = @defs.has_key?(line) ? :multiple : sexp
29
+ def store_sexp(sexp, line)
30
+ @defs[line] = @defs.key?(line) ? :multiple : sexp
31
+ end
30
32
  end
31
33
  end
32
34
 
@@ -2,196 +2,200 @@
2
2
  #
3
3
  # Used by the LiveAST test suite.
4
4
  #
5
- module LiveAST::RubyParser::Test
6
- class << self
7
- #
8
- # Whether this is Ryan Davis's unified sexp format.
9
- #
10
- def unified_sexp?
11
- true
12
- end
5
+ module LiveAST
6
+ class RubyParser
7
+ module Test
8
+ class << self
9
+ #
10
+ # Whether this is Ryan Davis's unified sexp format.
11
+ #
12
+ def unified_sexp?
13
+ true
14
+ end
13
15
 
14
- #
15
- # Whether the unparser output matches that of ruby2ruby.
16
- #
17
- def unparser_matches_ruby2ruby?
18
- true
19
- end
20
- end
16
+ #
17
+ # Whether the unparser output matches that of ruby2ruby.
18
+ #
19
+ def unparser_matches_ruby2ruby?
20
+ true
21
+ end
22
+ end
21
23
 
22
- #
23
- # no_arg_def(:f, "A#f") returns the ast of
24
- #
25
- # def f
26
- # "A#f"
27
- # end
28
- #
29
- def no_arg_def(name, ret)
30
- s(:defn, name, s(:args), s(:str, ret))
31
- end
24
+ #
25
+ # no_arg_def(:f, "A#f") returns the ast of
26
+ #
27
+ # def f
28
+ # "A#f"
29
+ # end
30
+ #
31
+ def no_arg_def(name, ret)
32
+ s(:defn, name, s(:args), s(:str, ret))
33
+ end
32
34
 
33
- #
34
- # singleton_no_arg_def(:f, "foo") returns the ast of
35
- #
36
- # def self.f
37
- # "foo"
38
- # end
39
- #
40
- def singleton_no_arg_def(name, ret)
41
- s(:defs, s(:self), name, s(:args), s(:str, ret))
42
- end
35
+ #
36
+ # singleton_no_arg_def(:f, "foo") returns the ast of
37
+ #
38
+ # def self.f
39
+ # "foo"
40
+ # end
41
+ #
42
+ def singleton_no_arg_def(name, ret)
43
+ s(:defs, s(:self), name, s(:args), s(:str, ret))
44
+ end
43
45
 
44
- #
45
- # no_arg_def_return(no_arg_def(:f, "A#f")) == "A#f"
46
- #
47
- def no_arg_def_return(ast)
48
- ast[3][1]
49
- end
46
+ #
47
+ # no_arg_def_return(no_arg_def(:f, "A#f")) == "A#f"
48
+ #
49
+ def no_arg_def_return(ast)
50
+ ast[3][1]
51
+ end
50
52
 
51
- #
52
- # binop_def(:f, :+) returns the ast of
53
- #
54
- # def f(x, y)
55
- # x + y
56
- # end
57
- #
58
- def binop_def(name, op)
59
- s(:defn,
60
- name,
61
- s(:args, :x, :y),
62
- s(:call, s(:lvar, :x), op, s(:lvar, :y)))
63
- end
53
+ #
54
+ # binop_def(:f, :+) returns the ast of
55
+ #
56
+ # def f(x, y)
57
+ # x + y
58
+ # end
59
+ #
60
+ def binop_def(name, op)
61
+ s(:defn,
62
+ name,
63
+ s(:args, :x, :y),
64
+ s(:call, s(:lvar, :x), op, s(:lvar, :y)))
65
+ end
64
66
 
65
- #
66
- # singleton_binop_def(:A, :f, :+) returns the ast of
67
- #
68
- # def A.f(x, y)
69
- # x + y
70
- # end
71
- #
72
- def singleton_binop_def(const, name, op)
73
- s(:defs,
74
- s(:const, const),
75
- name,
76
- s(:args, :x, :y),
77
- s(:call, s(:lvar, :x), op, s(:lvar, :y)))
78
- end
67
+ #
68
+ # singleton_binop_def(:A, :f, :+) returns the ast of
69
+ #
70
+ # def A.f(x, y)
71
+ # x + y
72
+ # end
73
+ #
74
+ def singleton_binop_def(const, name, op)
75
+ s(:defs,
76
+ s(:const, const),
77
+ name,
78
+ s(:args, :x, :y),
79
+ s(:call, s(:lvar, :x), op, s(:lvar, :y)))
80
+ end
79
81
 
80
- #
81
- # binop_define_method(:f, :*) returns the ast of
82
- #
83
- # define_method :f do |x, y|
84
- # x * y
85
- # end
86
- #
87
- # binop_define_method(:f, :-, :my_def) returns the ast of
88
- #
89
- # my_def :f do |x, y|
90
- # x - y
91
- # end
92
- #
93
- def binop_define_method(name, op, using = :define_method)
94
- s(:iter,
95
- s(:call, nil, using, s(:lit, name)),
96
- s(:args, :x, :y),
97
- s(:call, s(:lvar, :x), op, s(:lvar, :y)))
98
- end
82
+ #
83
+ # binop_define_method(:f, :*) returns the ast of
84
+ #
85
+ # define_method :f do |x, y|
86
+ # x * y
87
+ # end
88
+ #
89
+ # binop_define_method(:f, :-, :my_def) returns the ast of
90
+ #
91
+ # my_def :f do |x, y|
92
+ # x - y
93
+ # end
94
+ #
95
+ def binop_define_method(name, op, using = :define_method)
96
+ s(:iter,
97
+ s(:call, nil, using, s(:lit, name)),
98
+ s(:args, :x, :y),
99
+ s(:call, s(:lvar, :x), op, s(:lvar, :y)))
100
+ end
99
101
 
100
- #
101
- # binop_define_method_with_var(:method_name, :/) returns the ast of
102
- #
103
- # define_method method_name do |x, y|
104
- # x / y
105
- # end
106
- #
107
- def binop_define_method_with_var(var_name, op)
108
- s(:iter,
109
- s(:call, nil, :define_method, s(:lvar, var_name)),
110
- s(:args, :x, :y),
111
- s(:call, s(:lvar, :x), op, s(:lvar, :y)))
112
- end
102
+ #
103
+ # binop_define_method_with_var(:method_name, :/) returns the ast of
104
+ #
105
+ # define_method method_name do |x, y|
106
+ # x / y
107
+ # end
108
+ #
109
+ def binop_define_method_with_var(var_name, op)
110
+ s(:iter,
111
+ s(:call, nil, :define_method, s(:lvar, var_name)),
112
+ s(:args, :x, :y),
113
+ s(:call, s(:lvar, :x), op, s(:lvar, :y)))
114
+ end
113
115
 
114
- #
115
- # binop_define_singleton_method(:f, :+, :a) returns the ast of
116
- #
117
- # a.define_singleton_method :f do |x, y|
118
- # x + y
119
- # end
120
- #
121
- def binop_define_singleton_method(name, op, receiver)
122
- s(:iter,
123
- s(:call, s(:lvar, receiver), :define_singleton_method,
124
- s(:lit, name)),
125
- s(:args, :x, :y),
126
- s(:call, s(:lvar, :x), op, s(:lvar, :y)))
127
- end
128
-
129
- #
130
- # no_arg_block(:foo, "bar") returns the ast of
131
- #
132
- # foo { "bar" }
133
- #
134
- def no_arg_block(name, ret)
135
- s(:iter, s(:call, nil, name), s(:args), s(:str, ret))
136
- end
137
-
138
- #
139
- # binop_block(:foo, :+) returns the ast of
140
- #
141
- # foo { |x, y| x + y }
142
- #
143
- def binop_block(name, op)
144
- s(:iter,
145
- s(:call, nil, name),
146
- s(:args, :x, :y),
147
- s(:call, s(:lvar, :x), op, s(:lvar, :y)))
148
- end
116
+ #
117
+ # binop_define_singleton_method(:f, :+, :a) returns the ast of
118
+ #
119
+ # a.define_singleton_method :f do |x, y|
120
+ # x + y
121
+ # end
122
+ #
123
+ def binop_define_singleton_method(name, op, receiver)
124
+ s(:iter,
125
+ s(:call, s(:lvar, receiver), :define_singleton_method,
126
+ s(:lit, name)),
127
+ s(:args, :x, :y),
128
+ s(:call, s(:lvar, :x), op, s(:lvar, :y)))
129
+ end
149
130
 
150
- #
151
- # binop_proc_new(:*) returns the ast of
152
- #
153
- # Proc.new { |x, y| x * y }
154
- #
155
- def binop_proc_new(op)
156
- s(:iter,
157
- s(:call, s(:const, :Proc), :new),
158
- s(:args, :x, :y),
159
- s(:call, s(:lvar, :x), op, s(:lvar, :y)))
160
- end
131
+ #
132
+ # no_arg_block(:foo, "bar") returns the ast of
133
+ #
134
+ # foo { "bar" }
135
+ #
136
+ def no_arg_block(name, ret)
137
+ s(:iter, s(:call, nil, name), s(:args), s(:str, ret))
138
+ end
161
139
 
162
- #
163
- # nested_lambdas("foo") returns the ast of
164
- #
165
- # lambda {
166
- # lambda {
167
- # "foo"
168
- # }
169
- # }
170
- #
171
- def nested_lambdas(str)
172
- s(:iter,
173
- s(:call, nil, :lambda),
174
- s(:args),
175
- s(:iter, s(:call, nil, :lambda), s(:args), s(:str, str)))
176
- end
140
+ #
141
+ # binop_block(:foo, :+) returns the ast of
142
+ #
143
+ # foo { |x, y| x + y }
144
+ #
145
+ def binop_block(name, op)
146
+ s(:iter,
147
+ s(:call, nil, name),
148
+ s(:args, :x, :y),
149
+ s(:call, s(:lvar, :x), op, s(:lvar, :y)))
150
+ end
151
+
152
+ #
153
+ # binop_proc_new(:*) returns the ast of
154
+ #
155
+ # Proc.new { |x, y| x * y }
156
+ #
157
+ def binop_proc_new(op)
158
+ s(:iter,
159
+ s(:call, s(:const, :Proc), :new),
160
+ s(:args, :x, :y),
161
+ s(:call, s(:lvar, :x), op, s(:lvar, :y)))
162
+ end
177
163
 
178
- # nested_defs(:f, :g, "foo") returns the ast of
179
- #
180
- # def f
181
- # Class.new do
182
- # def g
183
- # "foo"
184
- # end
185
- # end
186
- # end
187
- #
188
- def nested_defs(u, v, str)
189
- s(:defn,
190
- u,
191
- s(:args),
192
- s(:iter,
193
- s(:call, s(:const, :Class), :new),
194
- s(:args),
195
- s(:defn, v, s(:args), s(:str, str))))
164
+ #
165
+ # nested_lambdas("foo") returns the ast of
166
+ #
167
+ # lambda {
168
+ # lambda {
169
+ # "foo"
170
+ # }
171
+ # }
172
+ #
173
+ def nested_lambdas(str)
174
+ s(:iter,
175
+ s(:call, nil, :lambda),
176
+ s(:args),
177
+ s(:iter, s(:call, nil, :lambda), s(:args), s(:str, str)))
178
+ end
179
+
180
+ # nested_defs(:f, :g, "foo") returns the ast of
181
+ #
182
+ # def f
183
+ # Class.new do
184
+ # def g
185
+ # "foo"
186
+ # end
187
+ # end
188
+ # end
189
+ #
190
+ def nested_defs(u, v, str)
191
+ s(:defn,
192
+ u,
193
+ s(:args),
194
+ s(:iter,
195
+ s(:call, s(:const, :Class), :new),
196
+ s(:args),
197
+ s(:defn, v, s(:args), s(:str, str))))
198
+ end
199
+ end
196
200
  end
197
201
  end