在代码的eval之间维护局部变量

时间:2014-11-07 23:49:52

标签: ruby eval metaprogramming

考虑以下Ruby代码:

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"

目的是动态评估一些创建局部变量的代码,然后运行可以访问这些变量的其他代码。结果是:

c2:1:in `run': undefined local variable or method `x' for #<Foo:…> (NameError)

请注意,上述内容仅在eval突变绑定时才有效,只有在修改现有局部变量时才会这样做,而不会创建新变量。我不一定需要(或想要)每次运行来改变外部绑定,我只需要能够访问先前的绑定以进行后续的代码评估。

如何评估两个代码块并在它们之间维护局部变量?


对于好奇的人来说,真实世界的应用是custom tool,它可以执行脚本文件然后放入REPL。我希望REPL能够访问脚本文件创建的所有局部变量。

1 个答案:

答案 0 :(得分:1)

您需要存储Binding并重新使用相同的帐户。如果您反复调用binding - 即使在相同的范围内 - 您将获得新的绑定。因此,对于演示功能,我们可以这样做:

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