2014-03-29 240 views
0

的初学者一个简单的疑问句,我得到了以下错误消息从红宝石

NameError: undefined local variable or method 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

您的错误信息是不正确的。你显示的代码应该抱怨'x'不是'a'。 – lurker

+1

请重命名您的问题,以便解释您所要求的内容。 – BroiSatse

+0

您的问题陈述出错。你的意思是'放一个',而不是'puts x'? – lurker

回答

2
[1,2,3].each{|x| a = x} 
puts a 

此处您已在该块内创建了a。因此a只能在块内部访问。外界不知道谁是aa在词汇范围上可以阻止。因此,在您将a引入到该块的外部范围之前,您正试图使用​​MRI抱怨a。如果您也试图访问x,您将从MRI得到相同的抱怨。

[1].each do |x| 
    a = x 
    local_variables # => [:x, :a] 
end 

local_variables # => [] 

a = nil 
[1,2,3].each{|x| a = x} 
puts a 

现在你该块,这是最高级别之外创建a。现在#each方法采取块{ |..| ... }。在Ruby中,块是关闭,即它可以访问在块定义之前创建的外部变量。在块内部,您可以访问您在外部定义的a,并且还可以对其进行更新。现在,当bock将结束其执行时,您可以看到最后更新的值a。 *但是,如果您尝试访问x,您将得到相同的错误/投诉MRI * - 原因是,x从词汇范围到块,您创建它的时间,第一次范围,即在区块之外,它不存在。

a = nil 
[1].each do |x| 
    a = x 
    local_variables # => [:x, :a] 
end 

local_variables # => [:a] 
+0

谢谢。那么这是否意味着当变量a已经被声明时,它在块外部变得可识别,并且它的值将根据块内的值被设置? – user3476791

+0

Ruby Parser和IRB不具有100%相同的行为 - 记住这一点。找出行为的唯一真正方法是将代码的内容直接存储在.rb文件中并运行。 – shevy

+0

@mbratch现在清楚了,还是我错过了什么? –