2012-06-15 127 views
0

可能重複:
Is there a clean way to avoid calling a method on nil in a nested params hash?測試紅寶石多維散列

是否有一個簡單的方法來檢查,如果在一多維散列值,而沒有設置醒目的NoMethodException?

例:

do_x if cat['level1']['level2']['level3'] != 'value' 

的問題是,「(第二級)」可能根本不存在,因此接收爲零。

在PHP中,你可以在前面加一個'@'來抑制錯誤。

在Ruby中,我將不得不將檢查包裹在開始救援塊中。

是否有像PHP一樣的快速解決方案?

+2

多重複:http://stackoverflow.com/q/5429790/188031 – tokland

回答

1
do_x if cat['level1']['level2']['level3'] != 'value' rescue nil 

這是嵌入式rescue。問題是它可以隱藏錯誤,因爲它可以從任何RuntimeError中解救出來。你真的應該用正確的begin - rescue塊來代替:

begin 
    do_x if cat['level1']['level2']['level3'] != 'value' 
rescue NoMethodError => error 
    puts error.message 
end 

雖這麼說,爲什麼不消除嵌套和完全避免這個問題?

class NilClass 
    def[](key) 
    nil 
    end 
end 
0

你可以這樣它的行爲像你想運行您的代碼之前,無重新定義[]。 do_x if cat['level1'].try(:[], 'level2').try(:[], 'level3')所以如果do_x拋出一個異常不會被救出,你會真正看到,如果出現錯誤內do_x

+3

雖然這可能是工作在這裏,我強烈建議你不要這樣做,因爲這將非常有效地隱藏真正的錯誤,並使其成爲調試任何足夠複雜的應用程序的噩夢。當事情破裂時發生錯誤通常是一件好事:) –

0
class MyHash < Hash 
    def initialize(levels=0) 
    super() 
    self.default = MyHash.new(levels-1) if levels > 1 
    end 
end 

cat = MyHash.new(3) 

cat['level1']      #=> {} 
cat['level1']['level2']   #=> {} 
cat['level1']['level2']['level3'] #=> nil 
0

我會嘗試使用方法而不是救助:

do_x if cat['level1.level2.level3'] != 'value'