Monday, March 17, 2008

Rescue Me!

With all the talk recently about elegant nil handling in Ruby (like andand and if_not_nil and #try), I was surprised that no one mentioned using rescue.

Surely every ruby programmer knows rescue when used with its friend begin, but did you know rescue has a statement modifier form?

For example, the following throws an exception:
>> [ "Bacon Lettuce Tomato", nil ].collect {|s| s.upcase.reverse[0,6].reverse }
NoMethodError: You have a nil object when you didn't expect it!
The error occurred while evaluating nil.upcase
from (irb):15
from (irb):15:in `collect'
from (irb):15

Adding rescue nil after that ugly bit of method chaining gets me this:
>> [ "Bacon Lettuce Tomato", nil ].collect {|s| s.upcase.reverse[0,6].reverse rescue nil }
=> ["TOMATO", nil]

... and rescue "" gets me this, useful if I want to return all the same types:
>> [ "Bacon Lettuce Tomato", nil ].collect {|s| s.upcase.reverse[0,6].reverse rescue "" }
=> ["TOMATO", ""]

I haven't used this other than playing around in a console, so I don't really know if this has nasty side effects or not. Maybe there's a reason all these Ruby gurus haven't mentioned it...

1 comment:

Reginald Braithwaite said...

You linked to my post explaining the raitionale behind andand. If you scroll to the bottom, I explain my reasons for eschewing a rescue.

The synopsis is that a rescue will catch the case where something returns nil, but it will also catch other NoMethodErrors that really are errors you want raised.