2010-09-24 47 views
1

我注意到這在Ruby的If語句中有點怪異(我認爲)。例如:奇怪的紅寶石如果陳述問題

my_number = nil 
if my_number < 3 
    'number is less than 3' 
end 

很明顯,當你運行這段代碼時,你會得到一個「Fixnum與nil失敗的比較」錯誤。這裏有一些奇怪的東西。如果我在If語句中稍作修改以檢查是否爲零,則它工作正常。示例:

my_number = nil 
if my_number && my_number < 3 
    'number is less than 3' 
end 

添加對nil的檢查使其不會崩潰。這可能聽起來很愚蠢,但我無法弄清楚這是爲什麼。它不應該仍然會拋出一個錯誤?

感謝任何能解釋這一點的人。 :) 謝謝!

回答

4

布爾表達式被稱爲「短路」方式。也就是說,只要知道結果,它就不會繼續嘗試評估表達式。

所以它的if my_number因爲做法false,就沒有必要繼續下去,因爲false && <anything>永遠是假的。

這是一個很有用的語言特性,許多語言都是這樣工作的(原始的Visual Basic是我能想到的一個例外),因爲它可以讓你完成這種測試,而不需要繁瑣的嵌套'if'。

0

它可以測試爲零,所以if nil或類似的東西在幾乎所有語言都可以。

但是對於算術比較,如果它沒有拋出異常,它將不得不返回true或false。無論哪種方式都是有問題的。

真有種沒有意義,因爲零將是既<和>大於3

假幾乎是一樣糟糕,因爲現在nil < 3nil >= 3都是假的,這是不理想的。

因此,比較方法會引發異常。問題解決了。

1

這不是特定於Ruby的方式:我已經注意到這種行爲在我用過的所有語言中,從Pascal到Java。

如果布爾表達式b1 && b2 && b3 ... && bn,大多數語言保證,由左到右,如果一些bi原來是false,評估將被停止bi進行評估。 (因爲整個表達式是錯誤的)。與布爾||運算符相同。

0

nil是「falsy」。在IRB試試這個:

irb(main):001:0> puts "Nil is true " if nil 
=> nil 
irb(main):002:0> puts "Nil is not true " if !nil 
Nil is not true 
=> nil 

零是不一樣的假,但使其充當這樣幫助了很多圈等檢查:

false == nil 
=> false 

由於您的第一部分和是假的紅寶石做的懶惰的事情,甚至懶得評估下一位,如果它> 3.

0

什麼發生稱爲短路評估。你聲明可以被認爲是這樣的:

if(my_number) 
    if(my_number < 3) 
    'number is less than 3' 
    end 
end 

由於第一個條件是假的,我們沒有理由來評價語句的第二個條件 - 在my_number < 3部分。