What's New in Edge Rails: Object.try

Posted by ryan
at 9:49 PM on Wednesday, November 19, 2008

This feature is scheduled for: Rails v2.3/3.0

Those of you using Chris Wanstrath’s slick little try trick will now have access to that functionality in Rails with this ActiveSupport update.

Basically, try lets you attempt to invoke a method on an object without worrying about a NoMethodError being raised. If the method doesn’t exist, or if the target object nil, then nil will be returned without exceptions:

1
2
3
4
5
# No exceptions when receiver is nil
nil.try(:destroy) #=> nil

# Useful when chaining potential nil items
User.admins.first.try(:address).try(:reset)

Just a small little bit of syntactical candy pulled in from the community.

Update: You can now also use this trick for methods with arguments

tags: ruby, rubyonrails

Comments

Leave a response

  1. AnonymousNovember 20, 2008 @ 03:25 AM

    Wow. Gross.

  2. Mathijs KwikNovember 20, 2008 @ 03:41 AM

    I like the try-as-a-proxy thing better, since you can arguments: @some_text.try.sub(‘hello’, ‘goodbye’)

    you can pass blocks as well. @articles.try.each do |article| .... end

  3. kelyarNovember 20, 2008 @ 07:17 AM

    that’s great! i’m so tired of using lots of rescues after every method chain!

  4. DJNovember 20, 2008 @ 02:07 PM

    I can already see potential for abuse. But it might be nice in some cases.

  5. Kevin BallardNovember 20, 2008 @ 05:45 PM

    As Mathijs says, the try-as-proxy version is significantly better. It’s even being used in Chris’s own github-gem project (courtesy of me)!

    http://github.com/defunkt/github-gem/tree/master/lib%2Fgithub%2Fextensions.rb

  6. Anonymous CowardNovember 20, 2008 @ 08:38 PM

    Hmm… still prefer andand over this.

  7. FooNovember 21, 2008 @ 06:51 AM

    Is this better then using exception catching? How do you handle if the try doesn’t work?

  8. ActsAsFlinnNovember 21, 2008 @ 10:20 AM

    I hate this. Not because there is something better but because it legitimizes the bad code or environment conditions that lead up to this. Can we stop being enablers at some point?

  9. Ryan BatesNovember 21, 2008 @ 12:04 PM

    @Foo, catching the MethodMissing exception isn’t a good idea here because you don’t know how deep it is. The “try” method could be called early on and MethodMissing could happen deeper in the code and still be rescued.

    I suppose it would be possible to parse the stack trace and determine how deep MethodMissing was, but that could get ugly.

  10. David BradyNovember 21, 2008 @ 02:54 PM

    I think there’s a good time and place for this kind of code, but try is just about the worst possible implementation of this kind of trick.

    1. “try” in any other language implies exception handling, and this meme is so well-embedded that saying “well this is Ruby” is not an adequate counterargument. There exist better alternatives: “andand” and “maybe” come to mind.

    2. Object.try takes method invocation syntax and turns it into symbol-passing syntax. Fail. The other major place we see this is symbol_to_proc, but at least there the symbols are tagged with & so you know something’s going on. andand and turtles both preserve method-passing.

    3. Try is incomplete: it does not accept blocks to be passed to the tried method. maybe, andand and turtles both accept blocks.

    4. Try is VERY incomplete: it does not accept function arguments to be passed to the tried method. maybe, andand, and turtles take arguments.

    For my money and time, andand is better on every count. Maybe and Turtles are better on three of the four, and turtles was literally written as a joke.

    I mean no disrespect to Chris here; Object.try is the start of a good idea. But it isn’t complete and it isn’t robust. People who want to embrace the if_not_nil concept will need to deal with Object.try in their code AND still go get maybe or andand.

    Including it in Rails doesn’t mean syntactic sugar. It means another turd speck has been added to the Rails brownie.

  11. FachhandelNovember 25, 2008 @ 03:18 AM

    kelyar say: “that’s great! i’m so tired of using lots of rescues after every method chain!” That´s full right..

  12. John WellsDecember 17, 2008 @ 10:23 AM

    Why on earth was this chosen instead of andand? Disappointing…

  13. asdsdJanuary 07, 2009 @ 03:58 PM

    User.admins.first.address.reset rescue nil Is there some difference?