Last updated on December 20, 2021
Ruby 2.3.0 introduced the Safe Navigation Operator &.. Over the last couple of months, the safe operator has played a big part of the programming flow of my team (mainly due to the CMS integration with the marketing website) and it has saved us many lines of code. Let’s explore what it is and what are the pros and cons of using it.
A lot of comparison can be drawn from Ruby’s try! method and the safe operator &.
However, there are several differences that you should be aware of.
Method name is syntactically required when using &.
obj.try! {} # valid
obj&. {} # syntax error
When using the &. attribute, the assignment is valid
obj&.attr = "Tobias Funke" # valid
obj.try!(:attr) = "Tobias Funke" # syntax error
Generally speaking, the safe operator is better compared to Rails’ try or Ruby’s try! (even though that this might be subjective depending on the developer). There are several points for this argument
Regarding my last point, I came across this benchmark which compared the safe operator against other common methods for testing for nil
.
The safe operator had a similar speed compared to a simple check for nil && nil.length and it was ~4 times faster compared to Rails’ try method.
In some cases, our object might be nil which might break our code if we call a specific method on that object. We might want to prevent our app from raising an error and the safe operator &. will do exactly that - it will return nil after our method call even if our object is nil.
Let’s say that we have a user with a team and we want to get the name of that team. If the user is present, it will work as expected.
user.team.name
=> "The Bluth Company"
But what if the the user is not present?
user
=> nil
user.team
Traceback (most recent call last):
1: from (irb):9
NoMethodError (undefined method `team' for nil:NilClass)
One solution is to create an if statement
if user.present?
teamName = user.team.name
else
teamName = nil
end
Or we can use the safe operator
teamName = user&.team.name
=> nil
Let’s expand this problem further. What if the user is present, but it doesn’t have a team?
teamName = user&.team.name
Traceback (most recent call last):
1: from (irb):33
NoMethodError (undefined method `name' for nil:NilClass)
We can quickly fix this error using a safe operator.
teamName = user&.team&.name
=> nil
While conducting my research for this article, I found some comments and articles that criticize the safe operator. Even though these comments might have merit, I think it is a great addition to the toolkit of a Rails developer.
I learnt that there are several potential problems with the safe operator that you should be aware of.
Articles, guides and interviews about web development and career progression.
Max 1-2x times per month.