2011-12-14 95 views
7

如果我執行這個Ruby代碼:紅寶石:法莫名其妙地覆蓋並設置爲無

def foo 
    100 
end 

p defined?(foo), foo 
if false 
    foo = 200 
end 
p defined?(foo), foo 

我得到的輸出是:

"method" 
100 
"local-variable" 
nil 

可爲什麼foo設置爲nil有人向我解釋不執行if後?這是預期的行爲還是ruby bug?

+1

的方法不會被覆蓋,並設置爲零的吳哥窟(https://www.destroyallsoftware.com/talks/wat)的樂趣。 `放foo()`仍然有效。會發生什麼是一個局部變量`foo`已經存在。對不起,但我無法回答爲什麼會發生這種情況。 – Mischa 2011-12-14 14:23:14

+0

我也無法回答爲什麼。但是,如果局部變量和方法之間存在不確定性,請務必在方法中使用`self.foo`,爲變量使用`foo`。 – 2011-12-14 14:26:08

回答

5

作業左側的名稱被設置爲nil,即使代碼不能像if false的情況那樣到達。

>> foo 
NameError: undefined local variable or method `foo' for main:Object 
... 
>> if false 
.. foo = 1 
.. end #=> nil 
>> foo #=> nil 

當紅寶石試圖解決裸字,首先查找本地變量(有一個在鎬頭書,我似乎不能在此刻找到一個參考)。由於您現在有一個名爲foo的顯示屏,因此它會顯示nil。正如Mischa指出的那樣,該方法仍然可以稱爲foo()

1

這是我的朋友和Ruby超級高手喬希奇克說的話:

當紅寶石看到分配,它初始化在當前範圍內的變量,並將其設置爲零。由於分配沒有運行,它沒有更新foo的值。

如果語句不像塊那樣改變範圍。這也是

for x in xs 

xs.each { |x| } 

這裏之間最重要的區別是另外一個例子:

a = 123 if a # => nil 
a # => nil 

我們應該不能說if a,因爲我們從來沒有a,但紅寶石看到a = 123並初始化a,然後到達if a在這一點anil

我真的認爲這是一個解釋器的怪癖。加里·哈特使得與a = a

-Josh