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?

Community
  • 1
  • 1
Arne TR
  • 46
  • 4

4 Answers4

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

This is the inline rescue. The problem is that it can hide bugs since it rescues from any RuntimeError. You really should use proper begin-rescue blocks instead:

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

With that said, why not eliminate the nesting and avoid the issue altogether?

do_x if cat['level1.level2.level3'] != 'value'
Matheus Moreira
  • 17,106
  • 3
  • 68
  • 107
0

you can redefine [] on nil so it behaves like you want before you run your code:

class NilClass
  def[](key)
    nil
  end
end
davidrac
  • 10,723
  • 3
  • 39
  • 71
  • 3
    While this could work here, I would strongly advise you not to do this, as this will very effectively hide real bugs and make it a nightmare to debug any sufficiently complex application. Having errors when things break is generally a good thing :) – Holger Just Jun 15 '12 at 19:51
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
megas
  • 21,401
  • 12
  • 79
  • 130
0

I would use try method instead of rescue. do_x if cat['level1'].try(:[], 'level2').try(:[], 'level3') so if do_x raises an exception it won't be rescued and you will actually see if something goes wrong inside do_x

Iuri G.
  • 10,460
  • 4
  • 22
  • 39