2011-06-17 40 views
13

Ruby的NilClass實例中的to_i方法返回零的事實背後的科學是什麼?返回或引發異常不會更符合邏輯?Ruby Nil and Zero

+3

相關:您可以使用'N =整數(STR)'如果你想提高對故障異常。 – Dogbert

回答

12

NilClass定義#to_i出於同樣的原因它定義了一個#to_a返回[].它給你正確的類型,但空之類的價值的東西。

這實際上非常有用。例如:

<%= big.long.expr.nil? ? "" : big.long.expr %> 

變爲:

<%= big.long.expr %> 

的效果好很多! (ERB是調用#to_s其中對於零,爲 「」)。而且:

if how.now.brown.cow && how.now.brown.cow[0] 
    how.now.brown.cow[0] 
else 
    0 
end 

變爲:僅需要表示時

how.now.brown.cow.to_a[0].to_i 

短轉化存在。長時間轉換是Ruby核心方法調用的轉換,它們需要非常接近的東西。如果您想要進行類型檢查,請使用它們。

即:

thing.to_int # only works when almost Integer already. NilClass throws NoMethodError 

thing.to_i # this works for anything that cares to define a conversion 
+0

*「好多了!」*是的,這取決於你和項目工作的其他人都知道Ruby以及你想要依賴不直觀行爲的程度。返回0而不是引發異常的'nil.to_i'在邏輯上沒有太大的意義。你怎麼能從'nil'得到'0'?它不像'nil == 0'返回true,但'to_i'意味着等價。 –

+4

@Ed S .:不,'to_int'意味着等價,'to_i'非常鬆散,它並不意味着什麼。 –

+1

偉大的答案!我總是忽略了長期的轉換,現在我可以理解它們以及紅寶石哲學中的合適性。 –

13

它適合放縱的紅寶石理念(相對於,例如,Python的嚴格性):

nil.to_i #=> 0 
"".to_i #=> 0 
"123hello".to_i #=> 123 
"hello".to_i #=> 0 

說實話,我認爲這是過於寬鬆。正如Zabba所述,您可以使用Kernel#Integer(string)進行嚴格轉換。

+3

你不需要使用正則表達式。如果你想在字符串不是完全數字時出錯(比如「123hello」),你可以這樣做:'Integer(「123hello」)'(引發'ArgumentError')。 – Zabba

+0

+1是的,它似乎過分寬容。很好地放。 – Peter

6

to_i表示「如果可以的話,將我轉換爲整數」。

如果你想要「如果你非常像整數,給我你的整數值,否則給一個NoMethodError」,然後使用.to_int

還有另外一個問題,詢問有關to_ito_int之間的區別,to_sto_str等讓我知道,如果你想我幫您找到它。

6

to_i協議說,你必須返回Integer,你不能引發異常。你的兩條建議至少違反了其中一條規則。所以,不,這些不僅不會更合乎邏輯,而且會變得無效。

但是,請注意,nil不會迴應to_int。如果它確實to_int作出迴應,那確實是「不合邏輯的」。

+1

協議說'to_i'必須返回一個整數並不會使這種行爲變得合乎邏輯,它只是使其符合規定(假設,即使不合邏輯,也最好符合它)。 –

1

如果你碰巧在Rails的,那麼你可以使用try

nil.to_i # => 0 
nil.try :to_i # => nil