我收到以下错误消息
NameError:未定义的局部变量或方法
a' for main:Object from (irb):2 from /usr/local/bin/irb:12:in
'
如果我的代码如下:
[1,2,3].each{|x| a=x}
puts x
但是,如果我在脚本的开头放一个句子,一切都很好。
a=nil
有人会告诉我为什么' a = nil'有必要的? 谢谢!
答案 0 :(得分:2)
[1,2,3].each{|x| a = x}
puts a
您在此处创建了a
。所以a
只能在块内访问。外面的世界不知道谁是a
。 a
在词法上限定为阻止。因此,当您在将a
引入块的外部范围之前尝试使用a
时, MRI 抱怨x
。如果您也尝试访问[1].each do |x|
a = x
local_variables # => [:x, :a]
end
local_variables # => []
,那么您将从 MRI 获得相同的投诉。
a = nil
[1,2,3].each{|x| a = x}
puts a
a
现在你在区块外创建了#each
,这是顶级的。现在{ |..| ... }
方法占用了一个块a
。块是Ruby中的闭包,即它可以访问外部变量,这些变量是在定义块之前创建的。在块中,您可以访问您在外部定义的a
并进行更新。现在,当bock将结束执行时,您可以看到x
的上次更新值。 *但是,如果您尝试访问x
,您将从 MRI 获得与上面相同的错误/抱怨。* - 原因是,{{ 1}}词法作用于块,你在第一时间创建它,外部作用域,即在块之外,它没有存在。
a = nil
[1].each do |x|
a = x
local_variables # => [:x, :a]
end
local_variables # => [:a]