Ruby try &.
Safe navigation operator
Ruby 2.3.0 introduces new operator &. which acts like object#try from ActiveSupport.
person = Person.new
puts "Money: #{person&.account&.money}"
Not so simple
You may guest that foo&.bar is equivalent to (foo == nil) ? nil : foo.bar. But it’s not.
def foo
obj = nil
(obj == nil) ? nil : obj.attr
end
foo += 1 # undefined method `+' for nil:NilClass
While using operator &. you are safe.
obj = nil
obj&.attr += 1 # nil
The operator &. checks for nil value and gracefully interrupts whole expression and return nil.
Using with Hashes
The same semantic for Hashes may looks like this
h = {key1: 1, key2: { subkey: 's'} }
p h[:key3]&.[](:subkey)
But it’s better to use dig method since ruby 2.3
p h.dig :key3, :subkey
p h&.dig :key3, :subkey # even that safe
Attention
Some cases may lead to misunderstanding.
- The
&.syntax only skips nil but recognizes false. It is not exactly equivalent to thes1 && s1.s2 && s1.s2.s3syntax. The right interpretation isfoo&.bar (foo == nil) ? nil : foo.bar # almost the same, see above - You should avoid using
nil?check with&.operator. It handles nil already and you may get unexpected resultnil&.nil? # => nil nil.nil? # => true - The undefined variables are still undefined
obj&.attr # undefined local variable or method `obj' for main:Object obj = 1 obj&.attr # undefined method `attr' for 1:Integer