
Try(), try() again in Rails - joshuacc
http://everydayrails.com/2011/04/28/rails-try-method.html
======
JonnieCache
My preferred solution for a safe navigation operator in ruby is the andand gem

<http://andand.rubyforge.org/>

To translate one of the example from the OP:

    
    
        <%= @product.manufacturer.andand.name %>
        
          <% if current_user.andand.is_admin? %>
            <%= link_to 'Edit', edit_product_path(@product) %>
          <% end %>
    

This syntax is simpler and more readable, even if there is more voodoo
involved. Since when did we as rails devs care about that?

~~~
Hovertruck
I'm not sure I agree on the syntax being simpler/more readable... try() seems
pretty clear-cut to me.

~~~
themgt
I prefer the implementation of Mongoid's #do_or_do_not, which checks for the
method's existence rather than the object's

([http://rubydoc.info/github/mongoid/mongoid/master/Mongoid/Ex...](http://rubydoc.info/github/mongoid/mongoid/master/Mongoid/Extensions/Object/Yoda))

------
mr_justin
> I know I sometimes forget about it, and I’ve looked at enough code from
> other developers to know that I’m not the only one.

I think by and large, most people don't use it not out of forgetfulness, but
out of disdain for willy nilly calling methods on objects without knowing what
might happen.

------
deadbadger
On the subject of try() chaining, there's always Ick, which implements (among
other things) a kind of Maybe monad for Ruby. This acts as a self-propagating
nil guard, so you're able to write things like:

    
    
      maybe(Person.find("geoff")) { |person| person.manager.authority_level.permissions }
    

without worrying about chaining things yourself. I've not used it in
production code yet, as I haven't really had a chance to do due diligence on
it - be interested to hear if anyone else has used it in anger...

<http://ick.rubyforge.org/>

~~~
gecko
There's a solution in Smalltalk that I'm wondering why no one's brought to
Ruby. In applications where this pattern is useful, there's a class, Null,
with the singleton null (in contrast to UndefinedObject and its singleton
nil). nil raises an exception, but null simply eats all messages sent to it,
much like the maybe monad you listed.

This makes it really easy to mix and match the two paradigms in your code: in
places where it's okay for the object to just eat messages, you return null.
In places where no value is a real error, you return nil. Either value can be
converted to the other with a one-line statement, and to existing code, null
looks like nil when queried (i.e., isNil returns true, ifNil: and ifNotNil:
and friends behave as if null were nil, etc.).

Seems as if writing a similar tool for Ruby would be trivial.

~~~
deadbadger
But then don't you have to make your choice about whether no-value is an error
when you return the value, rather than when you make the call?

With #try et al it's made obvious at the point the message is sent whether
it'll be swallowed by nil (and that you're fine with this). To me this seems
safer than having two classes of entities knocking round, one swallowing
messages and one not, and no way to tell at a glance which is which.

(I've not used Smalltalk btw, so apologies if I've misunderstood...)

~~~
gecko
You can use it either way. I usually employ it at return time, because usually
there are classes (little-case C) of return types that I'm fine with being
ignored. A list of objects that need to be signaled on an event, for example:
it's fine with me if that's not initialized, so it's okay to return null
there.

Sometimes, you want to do what you're saying, and have a brief snippet where
you switch to message-eating null. That's easy enough using the built-in
ifNil: message:

    
    
        (foo ifNil: [ null ]) baz quux frob: bar.
    

If this is common, it'd be easy to add a method "try" to Object that returned
self, and one to UndefinedObject that returned null, at which point you could
do the same thing as Ruby:

    
    
        foo try baz quux frob: bar.
    

So either way, really.

