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

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

此问题在此处已有答案

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,但是,我不能预测哪些元素会存在。

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

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

xzabzqsa

xzabzqsa1#

Ruby 2.3.0在HashArray上都引入了一个名为dig的方法。
如果在任何嵌套级别缺少元素,则返回nil

  1. h1 = {}
  2. h2 = { a: {} }
  3. h3 = { a: { b: 100 } }
  4. h1.dig(:a, :b) # => nil
  5. h2.dig(:a, :b) # => nil
  6. h3.dig(:a, :b) # => 100

您的用例将如下所示:

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

dgiusagp2#

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

  1. @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):

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

pu82cl6c3#

我会这样做:

  1. begin
  2. @param_info.fetch(:drug).fetch(:name)
  3. rescue KeyError
  4. # handle key not found
  5. end

您可以在单个函数中执行此操作:

  1. def param_info_key(info, key1, key2)
  2. info.fetch(key1).fetch(key2)
  3. rescue KeyError
  4. nil
  5. end
  6. param_info_key({}, :a, :b) # nil
  7. param_info_key({a: {}}, :a, :b) # nil
  8. param_info_key({a: {b: "foo"}}, :a, :b) # "foo"

样品:

  1. irb(main):001:0> s = {}
  2. => {}
  3. irb(main):002:0> begin
  4. irb(main):003:1* s.fetch(:foo).fetch(:bar)
  5. irb(main):004:1> rescue KeyError
  6. irb(main):005:1> puts "Key not found"
  7. irb(main):006:1> end
  8. Key not found
  9. => nil
展开查看全部
xmq68pz9

xmq68pz94#

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

  1. irb(main):001:0> def checker(val)
  2. irb(main):002:1> unless val.nil?
  3. irb(main):003:2> puts 'working on the railroad'
  4. irb(main):004:2> end
  5. irb(main):005:1> end
  6. => nil
  7. irb(main):006:0> x = nil
  8. => nil
  9. irb(main):007:0> checker(x)
  10. => nil
  11. irb(main):008:0> y = 1
  12. => 1
  13. irb(main):009:0> checker(y)
  14. working on the railroad
  15. => nil
  16. irb(main):010:0>
展开查看全部

相关问题