我有以下代码:
code = "def hi; \"hi!\"; end"
eval code
hi == "hi!" # true
我可以访问方法hi
,因为当它在评估代码中定义时,它被定义为主对象的方法。
但是,这也意味着评估的代码可以访问我在其外部定义的内容:
def hi; "hi!"; end
eval "hi == \"hi\"" # => true
我希望有一个单独的命名空间,我可以在其中运行已评估的代码;我该怎么做?
我尝试使用module_eval
并使用模块作为命名空间,但我无法定义方法或类,并在另一个评估中访问它。
答案 0 :(得分:2)
您可以像这样评估对象内部的代码:
module DSL
def helper_method_to_be_used_by_evaled_code
# ...
end
# ...
end
container = Object.new
container.extend(DSL)
File.open(eval_file1, 'r') {|f| container.instance_eval(f.read, eval_file1)}
File.open(eval_file2, 'r') {|f| container.instance_eval(f.read, eval_file2)}
通过这种方式,您可以控制是否在evals之间保留定义:您可以重用container
实例或处理它并创建新实例。这适用于方法定义和常量,在这些调用之间不保留局部变量。
此外,您可能希望查看Object
模式,而不是BlankState
。 “blankslate”是一个例子。
答案 1 :(得分:0)
似乎你不是在谈论让模块成为评估代码的一部分,所以像这样的东西应该可以正常工作:
module EvalMethods
class << self
code = "def hi; \"hi!\"; end"
eval code
end
end
puts EvalMethods::hi == "hi!"