The Safe Navigation Operator (&.) in Ruby
Safe Navigation Operator(&.) has entered our life with version 2.3.0 of Ruby.
This operator will be very helpful to keep our code clean. It has been available in C# and Kotlin with a different syntax.
What does it do?
For example:
We have a money transfer has been prepared yet to send money from Turkey to Germany.
The money transfer has status
and transaction
relation. If transaction
record is present and transaction.status
is commit
, we can set the transfer.status
from preparing
to ready_to_pay
.
We can implement the following scenarios:
transfer = Transfer.preparing.find_by(reference_code: 'INT201807240023', owner: user)
Recipient can be withdraw money if everything is okay.
- Scenario 1: No method error:
If we write the controls as below, our inbox will be filled with crash reports.
The transaction may not have created yet. For this reason it takes the value nil
.
if transfer.transaction.commit?
transfer.ready_to_pay!
end
# => NoMethodError: undefined method 'commit?' for nil:NilClass
- Scenario 2: Lengthy and dirty solution
if transfer && transfer.transaction && transfer.transaction.commit?
transfer.ready_to_pay!
end
- Scenario 3: Maybe a little better:
if transfer.try(:transaction).try(:commit?)
transfer.ready_to_pay!
end
- Scenario 4: Best for now:
if transfer&.transaction&.commit?
transfer.ready_to_pay!
end
To me, it is cleaner and cooler than the other 3 methods.
If we think about it a little:
Bad news:
The &. only skips the nil
. In the above example, the transfer.transaction take the any value instead of nil
, so the error wil be occurred. Because other classes like FalseClass
or User
not have commit?
method.
Of course, ActiveRecord relationship objects will not take the irrelevant value. But we will not only use this operator &.
for ActiveRecord objects.
Greats:
The possibility of a method returning more than one type of value: it may indicate that there is some dirty work being done here.
Yes, the Ruby isn’t typesafe currently, but it’s not a dirtytype language either.
Therefore, it can be used easily in clean works 😄.
That’s it for now.