mvz-live_ast 1.1.1 → 1.1.2

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.
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