ruby-on-rails 访问嵌套哈希时如何避免nil元素出现NoMethodError?[duplicate]

zbdgwd5y  于 2022-12-15  发布在  Ruby
关注(0)|答案(4)|浏览(157)

此问题在此处已有答案

Ruby Style: How to check whether a nested hash element exists(16个答案)
How to avoid NoMethodError for missing elements in nested hashes, without repeated nil checks?(16个答案)
六年前关闭了。
如果我试图访问一个不存在的hash元素,我得到NoMethodError: undefined method '[]' for nil:NilClass,但是,我不能预测哪些元素会存在。

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

当一个元素意外地为nil时,如何避免引发这个错误?

xzabzqsa

xzabzqsa1#

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')
dgiusagp

dgiusagp2#

如果我正确理解了您的问题,即在属性值缺失的情况下进行宽容,那么您可以尝试以下操作:

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

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

更新日期:

为了处理不存在的密钥,您可以尝试以下操作。(Got this hint from Equivalent of try for a hash):

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

pu82cl6c3#

我会这样做:

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
xmq68pz9

xmq68pz94#

你可以简单地使用unless来测试它:

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>

相关问题