Calling Methods on Potential Nil Objects in Rails

Rails adds a pretty cool Object#try method. From Rails doc:

try(method, *args, &block)

This Invokes the method identified by the symbol method, passing it any arguments and/or the block specified, just like the regular Ruby Object#send does.

Unlike that method however, a NoMethodError exception will not be raised and nil will be returned instead, if the receiving object is a nil object or NilClass.

This is how you use it:

>> "Don'tRepeatYourselfs ".try(:underscore).try(:capitalize).try(:chop!).try(:chop!)
=> "Don't_repeat_yourself"
>> nil.try(:underscore).try(:capitalize).try(:chop!).try(:chop!)
=> nil

You can see it is not so DRY if you want to chain a lot of methods together, as is commonly the case in a Rails app. Inspired by RSpec’s stub_chain method, I wrote a little try_chain method:

class Object
  def try_chain(*args)
    args.size > 1 ? eval("self.try(args[0]).try_chain(#{args[1..-1].inspect[1..-2]})") : self.try(args[0])
  end
end
>> "Don'tRepeatYourselfs ".try_chain(:underscore, :capitalize, :chop!, :chop!)
=> "Don't_repeat_yourself"
>> nil.try_chain(:underscore, :capitalize, :chop!, :chop!)
=> nil

This is much cleaner and you don’t see the NoMethodError exception for nil:NilClass anymore. A future version will work with arguments as in “Don’tRepeatYourself”.try(:sub, ‘Repeat’, ‘Shoot’).