eval方法有一个可选的参数--binding,如果为指定的话,那么表达式的值就会是一个具体的范围或上下文环境绑定。不过不必为这个有所意外,在 Ruby中,binding方法会返回一个Binding对象的实例,可以使用binding方法返回绑定的值。下是是ruby文档中提供的一个示例:
def getBinding(str) return binding() end str = "hello" puts( eval( "str + ' Fred'" ) ) #=> "hello Fred" puts( eval( "str + ' Fred'", getBinding("bye") ) ) #=> "bye Fred"
binding方法是内核的一个私有方法。getBinding方法通过调用binding方法返回当前上下文环境中str的值。在第一次调用 eval方 法的时候,当前上下文环境是main对象,并且str的值就是定义的局部变量str的值。在第二次调用eval方法是,当前的上下文环境则是 getBinding方法内部,局部变量str的值现在则为getBinding方法中参数str的值。Binding方法经常作为eval的第二个参 数,这样eval就不会因为找不到变量而出错了。
上下文环境也可以在类中定义。在下面的例子中,可以看到,实例变量@mystr和类变量@@x根据类而不同:
class MyClass @@x = " x" def initialize(s) @mystr = s end def getBinding return binding() end end class MyOtherClass @@x = " y" def initialize(s) @mystr = s end def getBinding return binding() end end @mystr = self.inspect @@x = " some other value" ob1 = MyClass.new("ob1 string") ob2 = MyClass.new("ob2 string") ob3 = MyOtherClass.new("ob3 string") puts(eval("@mystr << @@x", ob1.getBinding)) #=> ob1 string x puts(eval("@mystr << @@x", ob2.getBinding)) #=> ob2 string x puts(eval("@mystr << @@x", ob3.getBinding)) #=> ob3 string y puts(eval("@mystr << @@x", binding)) #=> main some other value
查看api
eval(p1, p2 = v2, p3 = v3, p4 = v4)
public
Evaluates the Ruby expression(s) in string. If binding is given, which must be a Binding object, the evaluation is performed in its context. If the optional filename and lineno parameters are present, they will be used when reporting syntax errors.
def get_binding(str) return binding end str = "hello" eval "str + ' Fred'" #=> "hello Fred" eval "str + ' Fred'", get_binding("bye") #=> "bye Fred"