之前未声明时,在 eval 之后未定义的局部变量或方法
undefined local variable or method after eval when not declared before
在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' 会是 'undefined local variable or method' 而变量 'a' 等于 4?
当您调用 eval
lambda 时,您会为您执行的代码创建一个新范围。
我想创建并执行一个新的 lambda。如果您之前声明 a
然后在您的 lambda 中使用一个名为 a
的变量,您应该使用相同的变量。但是如果你不在 lambda 之前声明 b
,eval
将创建自己的变量,并在最后删除它。
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__}"
运行上面的代码,可以看到outside binding和inside binding使用了不同的id。但共享同一个。当我们 运行 eval 时,ruby 将复制外部绑定,因此它将使用相同的 a;但是 b 是在内部绑定中定义的,当完成 eval 时,内部绑定将丢失,b 也是如此。实际上块范围与此相同。
在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' 会是 'undefined local variable or method' 而变量 'a' 等于 4?
当您调用 eval
lambda 时,您会为您执行的代码创建一个新范围。
我想创建并执行一个新的 lambda。如果您之前声明 a
然后在您的 lambda 中使用一个名为 a
的变量,您应该使用相同的变量。但是如果你不在 lambda 之前声明 b
,eval
将创建自己的变量,并在最后删除它。
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__}"
运行上面的代码,可以看到outside binding和inside binding使用了不同的id。但共享同一个。当我们 运行 eval 时,ruby 将复制外部绑定,因此它将使用相同的 a;但是 b 是在内部绑定中定义的,当完成 eval 时,内部绑定将丢失,b 也是如此。实际上块范围与此相同。