2014-03-29 241 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現在清楚了,還是我錯過了什麼? –