0

Possible Duplicate:
Is there a clean way to avoid calling a method on nil in a nested params hash?

Is there an easy way to check if a value in a multi dimensional hash is set without catching the NoMethodException?

Ex.:

do_x if cat['level1']['level2']['level3'] != 'value'

The problem is, that 'level2' might not even exist, so the receiver is nil.

In PHP you can just put an '@' in front to suppress the error.

In Ruby I would have to wrap the check in a begin-rescue block.

Is there a quick solution like in PHP?

4

4 回答 4

1
do_x if cat['level1']['level2']['level3'] != 'value' rescue nil

这是内联rescue。问题是它可以隐藏错误,因为它可以从任何 RuntimeError. 你真的应该使用正确的begin-rescue块来代替:

begin
  do_x if cat['level1']['level2']['level3'] != 'value'
rescue NoMethodError => error
  puts error.message
end

话虽如此,为什么不消除嵌套并完全避免这个问题呢?

do_x if cat['level1.level2.level3'] != 'value'
于 2012-06-15T19:05:41.913 回答
0
class MyHash < Hash
  def initialize(levels=0)
    super()
    self.default = MyHash.new(levels-1) if levels > 1
  end
end

cat = MyHash.new(3)

cat['level1']                     #=> {}
cat['level1']['level2']           #=> {}
cat['level1']['level2']['level3'] #=> nil
于 2012-06-15T20:03:36.087 回答
0

我会使用尝试方法而不是救援。 do_x if cat['level1'].try(:[], 'level2').try(:[], 'level3')因此,如果 do_x 引发异常,它将不会被救出,您实际上会看到 do_x 内部是否出现问题

于 2012-06-15T20:36:25.750 回答
0

您可以在 nil 上重新定义 [] ,使其在运行代码之前表现得像您想要的那样:

class NilClass
  def[](key)
    nil
  end
end
于 2012-06-15T19:15:02.293 回答