2013-10-25 34 views
10

考慮從一個新鮮開始會話以下IRB片段:||的奇怪含義和|| =在紅寶石(2.0,1.9.3,1.7.4的jruby)

irb:01> baz   # => NameError, baz is not defined 
irb:02> baz || baz = 0 # => NameError, baz is not defined 
irb:03> baz   # => nil 

baz是未定義的變量,並試圖評估它產生一個NameError。然而,不管怎樣,在這個操作之後,baz被定義,並且具有值nil。表面上看,值nil被分配給變量baz,即使沒有人(明確)要求它。有這種行爲可取的基礎語言理由嗎?

什麼是解釋這種行爲和其他類似的混亂結構,如這些規則:

irb:04> true if foo   # => NameError 
irb:05> foo     # => NameError; name still undefined 
irb:06> foo = (true if foo) # => nil 
irb:07> foo     # => nil; name defined as nil 
irb:08> true || i = 0 || j = 2 # => i and j are nil; || appears nonlazy 
irb:09> raise || quux = 1  # => RuntimeError, quux is nil 
+3

你實際上並沒有在你的任何例子中使用'|| =',問題標題有點誤導 – nzifnab

+0

更奇怪的是:'>> spam#=> NameError; >> spam || =「eggs」#=>「eggs」; >>垃圾郵件#=>「雞蛋」'。不一致。 – iamnotmaynard

+0

可能的重複[混淆內部的謬誤\'if \'塊]賦值操作(http://stackoverflow.com/questions/15183576/confusion-with-the-assignment-operation-inside-the-fallacy-if -block) –

回答

9

我不知道這是否是可取的,但它來自紅寶石如何解析的代碼。無論何時您有一段代碼分配一個局部變量,即使該代碼塊未被評估,該局部變量也會被分配爲nil。在你的代碼行2:因爲沒有這樣的變量被分配

baz || baz = 0 

第一baz返回一個錯誤。因此,它後面的分配baz = 0未評估,但仍然是分析,因此在上下文中創建一個局部變量baz,並初始化爲nil

對於您的第二個代碼塊,footrue if foofoo期間未分配。之後,foo = (true if foo)的任務分配爲foo,因此即使(true if foo)foo的分配之前被評估,該行中也不會引發錯誤。

+1

必須刪除我的評論,因爲你已經修復了你的答案;-)現在是正確的,對baz的賦值是**不執行,但是每當Ruby **解析器**檢測到一個賦值時,它就會爲它並設置爲「nil」。 –

+0

@DavidUnric您可能對我的回答早有說法,但現在,我認爲您的評論不會在我的回答之外添加任何信息。 – sawa