metaprogramming/ast/manipulation_no_parens.rb

tests/_examples/metaprogramming/ast/manipulation_no_parens.rb in the metorex repository.

# AST Manipulation without parentheses (where possible)

puts "=== eval ==="
puts eval "1 + 2 + 3"
x = 10
puts eval "x * 5"
# A local the eval binds belongs to the eval, so its value comes back as
# the eval's own answer rather than as a local out here.
puts eval("y = x + 20")

puts ""
puts "=== eval define method ==="
eval "def double(n)\n  n * 2\nend"
puts double 7

puts ""
puts "=== eval define class ==="
eval "class Point\n  def initialize(x, y)\n    @x = x\n    @y = y\n  end\n  def to_s\n    \"(\" + @x.to_s + \", \" + @y.to_s + \")\"\n  end\nend"
p = Point.new(3, 4)
puts p.to_s

puts ""
puts "=== parse ==="
ast = parse "1 + 2"
puts ast.class
puts ast.length

puts ""
puts "=== code generation ==="
eval "def add(a, b)\n  a + b\nend"
eval "def subtract(a, b)\n  a - b\nend"
eval "def multiply(a, b)\n  a * b\nend"
puts add(3, 4)
puts subtract(10, 3)
puts multiply(5, 6)

puts ""
puts "=== runtime modification ==="
class Calculator
  def compute(a, b)
    a + b
  end
end

calc = Calculator.new
puts calc.compute(5, 3)

Calculator.define_method("compute") do |a, b|
  a * b
end

puts calc.compute(5, 3)

Output:

=== eval ===
6
50
30

=== eval define method ===
14

=== eval define class ===
(3, 4)

=== parse ===
Array
1

=== code generation ===
7
7
30

=== runtime modification ===
8
15