Maintaining local variables between eval of code

筅森魡賤 提交于 2019-12-11 10:21:23

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!