问题
Consider the following Ruby code:
class Foo
def bar; 42; end
def run(code1,code2)
binding.eval(code1,'c1')
binding.eval(code2,'c2')
end
end
Foo.new.run "x=bar ; p x", "p x"
The intent is to dynamically evaluate some code—which creates local variables—and then run additional code that has access to those variables. The result is:
c2:1:in `run': undefined local variable or method `x' for #<Foo:…> (NameError)
Note that the above would only work if the eval
mutated the binding, which it only does when modifying existing local variables, not creating new variables. I do not necessarily need (or want) each run to mutate the outer binding, I just need to be able to access the previous binding for subsequent code evaluations.
How can I eval two blocks of code and maintain local variables between them?
For the curious, the real-world application of this is a custom tool that can execute a script file and then drop into a REPL. I want the REPL to have access to all local variables created by the script file.
回答1:
You need to store the Binding
and re-use the same one. If you call binding
repeatedly—even in the same scope—you will get a new binding. So, for the demo function, we can do this:
class Foo
def initialize; @b = binding; end
def bar; 42; end
def run(code)
@b.eval( code, '(yourcode)' )
end
end
f = Foo.new
f.run "x=bar ; p x" #=> 42
f.run "p x" #=> 42
来源:https://stackoverflow.com/questions/26811980/maintaining-local-variables-between-eval-of-code