What is the difference between `try` and `&.` (safe navigation operator) in Ruby
&.
works like #try!
, not #try
.
And here is description of #try!
(from documentation):
Same as #try, but will raise a NoMethodError exception if the receiving is not nil and does not implemented the tried method.
So basically it saves you from calling a method on nil
, but if an object is presented it will try to call its method as usual.
The quote is from Rails Documentation, and so it's important to emphasize
that Ruby does not provide #try
; it's provided by Rails, or more accurately ActiveSupport. The safe navigation operator (&.
) however, is a language feature presented in Ruby 2.3.0.
The try
method ignores a lot of things, it just gives it a shot and calls it a day if things don't work out.
The &
conditional navigation option will only block calls on nil
objects. Anything else is considered to be valid and will proceed with full consequences, exceptions included.
I am arriving to the party a bit late here, the other answers have covered how it works, but I wanted to add something that the other answers have not covered.
Your question asks What is the difference between try
and &.
in Ruby. Ruby being the key word here.
The biggest difference is that try
doesn't exist in Ruby, it is a method provided by Rails. you can see this or yourself if you do something like this in the rails console:
[1, 2, 3].try(:join, '-')
#=> "1-2-3"
However if you do the same thing in the irb console, you will get:
[1, 2, 3].try(:join, '-')
NoMethodError: undefined method `try' for [1, 2, 3]:Array
The &.
is part of the Ruby standard library, and is therefore available in any Ruby project, not just Rails.
In addition to the above answers, I am adding some examples.1
account = Account.new(owner: Object.new)
account.try(:owner).try(:address)
# => nil
account&.owner&.address
# => NoMethodError: undefined method `address' for #<Object:0x00559996b5bde8>`
account.try!(:owner).try!(:address)
# => NoMethodError: undefined method `address' for #<Object:0x00559996b5bde8>`
As we can see, try
doesn't check if the receiver responds to the given method or not. Whereas try!
and &.
behaves the same. If the receiver responds to the address
method, all of them will return the same result. I prefer using &.
as it looks more cleaner.
For more information on The Safe Navigation Operator (&.), I have found this blog really helpful https://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/