2015-05-10 24 views
0

當我意識到Enumerable#all?的行爲不像我認爲的那樣時,我今天正在調試一些代碼。.all上的奇怪行爲? {block}

我使用這種方法來確定何時立即返回一個值。它看起來是這樣的:

def some_method(hash) 
    unless hash.all? { |k, v| v.is_a? Float } 
    return hash 
    end 

    # some other business logic 
end 

但有時候這種方法被髮送空哈希和all?結果不是我所期望的。

下面是一些正常的情景:

[7] pry(main)> {'count' => 1}.all? { |k, v| v.is_a? Float } 
=> false 
[8] pry(main)> {'count' => 2.5 }.all? { |k, v| v.is_a? Float } 
=> true 

這裏就是它得到奇怪:

[6] pry(main)> {}.all? { |k, v| v.is_a? Float } 
=> true 

我不希望這個返回true,其實我會希望拿回"No method .is_a? for NilClass"但我反而回到了真實。有人知道爲什麼嗎?

的Ruby 2.2.0

+0

僅供參考您無法獲得無方法異常,因爲'.is_a?'是NilClass上的方法。 'nil.is_a? Float => false' – Charlie

回答

1

沒有辦法以來的塊永遠不會被執行拋出No method .is_a? for NilClass錯誤(除此之外.is_a?Object實現,NilClass顯然是從Object的。)

一可能期望all?在空枚舉器上返回false,但它就像是設計問題。

您可以在文檔中單擊show code,並確保在此方法實現中採用了方法「假設結果爲真並在返回false的第一個塊上將其變爲false」。

1

該文檔的關鍵部分是「該方法返回true,如果該塊永不返回false或零。」

隨着{}.all? { |k, v| v.is_a? Float }塊永遠不會執行(因爲地圖是空的)。因此,該塊永遠不會返回false或nil,因此該方法返回true。