访问嵌套哈希时如何避免nil元素的NoMethodError?

如果我尝试访问不存在的哈希元素,我会得到NoMethodError: undefined method '[]' for nil:NilClass 。 但是,我无法预测哪些元素会出现。

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

当元素意外nil时,如何避免引发此错误?

如果我正确理解您的问题,即在遗漏属性值的情况下使其宽容,那么您可以尝试以下方法:

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

这也可能返回nil ,但这将消除nil的错误undefined methods '[]' for nil:NilClass

更新:

为了处理不存在的密钥,您可以尝试以下方法。 ( 从等效的尝试获得这个提示 ):

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

Ruby 2.3.0在HashArray上引入了一个名为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') 

我会做这样的事情:

 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" 

样品:

 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 

你可以简单地使用,除非测试这个:

 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>