2013-11-21 145 views
6

如果我嘗試訪問不存在的散列元素,我得到NoMethodError: undefined method '[]' for nil:NilClass。但是,我無法預測哪些元素會出現。如何避免訪問嵌套散列時nil元素的NoMethodError?

@param_info = {} 
@param_info["drug"]["name"] 
# => NoMethodError: undefined method `[]' for nil:NilClass 

如何避免在元素出現意外時引發此錯誤nil

回答

5

如果我明白你的問題正確,即使它在案件中的屬性值缺少寬容,那麼你可以嘗試以下方法:

@param_info.try(:fetch, :drug).try(:fetch, :name) 

這可能會返回nil爲好,但是這將擺脫錯誤undefined methods '[]' for nil:NilClass

更新:

爲了處理不存在的鍵,你可以嘗試以下。 (Got this hint from Equivalent of try for a hash):

@param_info.try(:[], :drug).try(:[], :name) 
+0

我真的很喜歡多麼簡單,這是,但它仍然給我一個錯誤:關鍵未找到:「drddsug」(我把隨機字符測試) – Rob

+0

@Rob,請看我更新的答案。這將更加霧! – vee

+0

完美!謝謝 – Rob

0

您可以簡單地使用,除非來測試這一點:

irb(main):001:0> def checker(val) 
irb(main):002:1> unless val.nil? 
irb(main):003:2>  puts 'working on the railroad' 
irb(main):004:2>  end 
irb(main):005:1> end 
=> nil 
irb(main):006:0> x = nil 
=> nil 
irb(main):007:0> checker(x) 
=> nil 
irb(main):008:0> y = 1 
=> 1 
irb(main):009:0> checker(y) 
working on the railroad 
=> nil 
irb(main):010:0> 
1

我會做這樣的事情:

begin 
    @param_info.fetch(:drug).fetch(:name) 
rescue KeyError 
    # handle key not found 
end 

你可以做一個單一的功能:

def param_info_key(info, key1, key2) 
    info.fetch(key1).fetch(key2) 
rescue KeyError 
    nil 
end 

param_info_key({}, :a, :b) # nil 
param_info_key({a: {}}, :a, :b) # nil 
param_info_key({a: {b: "foo"}}, :a, :b) # "foo" 

Sa mple:

irb(main):001:0> s = {} 
=> {} 
irb(main):002:0> begin 
irb(main):003:1* s.fetch(:foo).fetch(:bar) 
irb(main):004:1> rescue KeyError 
irb(main):005:1> puts "Key not found" 
irb(main):006:1> end 
Key not found 
=> nil 
8

的Ruby 2.3.0上都HashArray是完全解決了這個問題介紹a new method called dig

如果在任何嵌套級別都缺少元素,則返回nil

h1 = {} 
h2 = { a: {} } 
h3 = { a: { b: 100 } } 

h1.dig(:a, :b) # => nil 
h2.dig(:a, :b) # => nil 
h3.dig(:a, :b) # => 100 

你的使用情況是這樣的:

@param_info.dig('drug', 'name')