eval/eval_scope_and_returns.rb
tests/_examples/eval/eval_scope_and_returns.rb in the metorex repository.
# What eval does with the scope around it: the class a definition lands in,
# the self the code runs against, the block the call was written with, and
# the way a return travels out.
class Cabinet
def stock
eval("class Shelf; end")
Shelf.name
end
end
p(Cabinet.new.stock)
p(Kernel.eval("self"))
p(Kernel.respond_to?(:eval))
p(method(:eval).call("2 * 3"))
class Speaker
def self.say
yield
end
end
begin
eval("Speaker.say") { "from the block" }
rescue LocalJumpError => refused
p(refused.class)
end
answer = -> do
proc do
eval("return :from_the_eval")
end.call
:never_reached
end.call
p(answer)
begin
proc { eval("return :nowhere") }.call
rescue LocalJumpError => stranded
p(stranded.class)
end
held = binding
eval("if false; counted = 1; end", held)
p(eval("counted", held))
source = <<SOURCE.b
# encoding: UTF-8
class Cabinet
Widthπ = 12
end
SOURCE
p(source.encoding)
eval(source)
p(Cabinet.constants(false).include?(:"Widthπ"))
p(Cabinet::Widthπ)
class Coerced
def to_str
"6 * 7"
end
end
p(eval(Coerced.new))
begin
eval("1", proc {})
rescue TypeError => refused
p(refused.message)
end
Output:
"Cabinet::Shelf"
Kernel
true
6
LocalJumpError
:from_the_eval
LocalJumpError
nil
#<Encoding:BINARY (ASCII-8BIT)>
true
12
42
"wrong argument type proc (expected binding)"