Ruby on rails 在访问嵌套哈希时,如何避免nil元素的NoMethodError?

Ruby on rails 在访问嵌套哈希时,如何避免nil元素的NoMethodError?,ruby-on-rails,ruby,hash,Ruby On Rails,Ruby,Hash,如果我试图访问一个不存在的散列元素,我会得到nil:NilClass的NoMethodError:undefined方法“[]”。然而,我无法预测会出现哪些元素 @param_info = {} @param_info["drug"]["name"] # => NoMethodError: undefined method `[]' for nil:NilClass 当元素意外为nil时,如何避免出现此错误?如果我正确理解了您的问题,即在缺少属性值的情况下使其原谅,那么您可以尝试以下操作

如果我试图访问一个不存在的散列元素,我会得到nil:NilClass的
NoMethodError:undefined方法“[]”。然而,我无法预测会出现哪些元素

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

当元素意外为
nil
时,如何避免出现此错误?

如果我正确理解了您的问题,即在缺少属性值的情况下使其原谅,那么您可以尝试以下操作:

@param_info.try(:fetch, :drug).try(:fetch, :name)
这也可能返回
nil
,但这将消除nil:NilClass

更新:

为了处理不存在的密钥,您可以尝试以下方法。():


您可以简单地使用,除非测试:

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> 

我会这样做:

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
Ruby 2.3.0在
散列
数组
上引入,完全解决了这个问题

如果在任何嵌套级别缺少元素,则返回
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')

我真的很喜欢这是多么简单,但它仍然给我一个错误:找不到键:“drddsug”(我输入随机字符进行测试)@Rob,请查看我的更新答案。这将更加令人迷惑不解@Rob Ruby 2.3.0引入了一个名为
Hash#dig
的新方法来解决这个问题。请看下面我的答案。
@param_info.dig('drug', 'name')