在Ruby中
2.1.2 :068 > a=1
=> 1
2.1.2 :069 > eval("a=4")
=> 4
2.1.2 :070 > a
=> 4
2.1.2 :071 > eval("b=4")
=> 4
2.1.2 :072 > b
NameError: undefined local variable or method `b' for main:Object
所以,问题是为什么变量'b'将是'未定义的局部变量或方法',但变量'a'等于4?
答案 0 :(得分:1)
当您调用eval
lambda时,您将为您执行的代码创建一个新范围。
这就像创建并执行一个新的lambda。如果您之前声明a
然后在lambda中使用名为a
的变量,则应使用相同的变量。但是如果你没有在lambda之前声明b
,eval
将创建自己的变量,并在最后删除它。
答案 1 :(得分:1)
puts "outside binding #{binding.__id__}"
a = 1
puts "outside a #{a.__id__}"
eval 'b="b"; puts "inside binding #{binding.__id__}"; puts "inside a #{binding.local_variable_get(:a).__id__}"; a="c"; puts "inside after a #{a.__id__}"'
puts "outside after a #{a.__id__}"
运行上面的代码,你可以看到外部绑定和内部绑定使用不同的id。但是分享同样的。当我们运行eval时,ruby将复制外部绑定,因此它将使用相同的a;但是b是在内部绑定中定义的,当eval完成时,内部绑定会丢失,因此是b。实际上块范围与此相同。