2012-02-02 51 views
5

可能重複:
Why a = a is nil in Ruby?爲什麼我可以在Ruby中爲自己分配一個未定義的變量並獲得零?

有一個,我們可以說,「奇特的現象」在Ruby中使用未定義的變量。它是這樣的:

# irb session follows 
# 
foo  # undefined local variable or method 'foo' 
bar  # same for 'bar' 
foo = bar # still same for 'bar' 
foo = foo # nil - HUH? 
foo  # is now set to nil!? 

爲什麼我一個未定義的變量在Ruby中分配給自己,並得到nil

請注意,我在這裏使用了Ruby 1.9.3。我不知道還有什麼其他的版本,這可能是真正的。

(感謝Gary伯恩哈特在他hilarious talk展示這種)

+1

推測「foo = foo」分兩步評估。第一個用默認值「聲明」變量,第二個將它賦值給自己。 – millimoose 2012-02-02 22:12:15

回答

2

無是在Ruby中的魔法,因爲這個想法,一切都是對象。實際上有一個單獨的無對象被賦值。當你做了

foo = bar 

「foo」變量出現並作爲值爲魔法零對象。在你完成任務之前,Ruby沒有辦法「知道」foo是什麼(它是一個變量嗎?一個方法調用?),但是一旦你完成這個任務,它就開始把它當作一個變量來處理。

+0

呃,'foo = foo'也沒有任何事先的陳述。 – 2012-02-02 22:25:58

+0

它確實如此,出於同樣的原因。零不是事物 - 這只是一個未定義值的佔位符。事情是這個任務,一旦Ruby看到這個任務,它就「決定」把這個標記作爲一個變量處理到「=」的左邊。 – theglauber 2012-02-02 22:43:17

+1

@theglauber,這並不完全解釋'foo = foo'。在'foo = bar'的情況下,如果foo和bar都未定義,則會引發異常。 'foo = foo'工作的奇怪情況是由於ruby解釋器在表達式評估之前執行初始化。基本上在左邊,foo被調用爲零;那麼當解釋者到達表達式評估的時候,右側的foo已經被初始化了。 – bigtunacan 2014-04-04 18:47:50

7

事實上,酒吧是不確定的,其實並不是最有趣的部分,因爲分配甚至不需要進行嘗試,例如

if false 
    foo = 1 
end 

foo的設置爲零。據我瞭解,局部變量範圍是靜態確定的,因爲它是在沒有實際運行代碼的情況下確定的,僅僅是通過分析它。 Ruby認爲賦值可能會發生,因此它會創建局部變量並將其設置爲零。請參閱http://ruby.runpaint.org/variables#local

+0

更好的是,要在if語句中分配的變量不必定義:'foo = wat if false' – 2016-04-01 23:19:23

相關問題