As a budding software developer, I am frequently browsing through Stack Overflow and the documentation for each programming language. More often than not, I encounter unfamiliar notations floating around, which I have to further lookup. And yes, I now understand more than ever that getting better at programming and getting better at googling go hand-in-hand. One of the things I found while working on a project was the safe navigation operator, &.
, which, as the name states, allows us to navigate safely through object relations in Ruby.
What is the safe navigation operator?
From official documentation, the "safe operator" allows us to skip a method call when the receiver is nil
. This means that the operator returns nil
if a method is called on a nil object rather than giving a noMethodError
. With this operator, we can easily chain methods that could return an empty value without breaking our code.
Here's a simple example:
Let's say we have a dog that belongs to a breed and we want to get the name of the breed. If the dog is present, the code will work as expected.
dog.breed.name
=> "Golden Retriever"
However, if the dog is not present. We will get an error.
dog
=> nil
dog.breed
...
NoMethodError (undefined method `breed' for nil:NilClass)
We can create an if statement to manage this error
if dog.present?
dogBreed = dog.breed.name
else
dogBreed = nil
end
or simply use the safe operator.
dogBreed = dog&.breed.name
=> nil
Note that &.
skips only one next call, so for a longer chain it is necessary to add the operator on each level. Say, if the dog is present but doesn't have a breed.
dogBreed = dog&.breed.name
...
NoMethodError (undefined method `name' for nil:NilClass)
One solution would be to set up the &&
conditional
if dog && dog.breed
=> nil
or we can use the safe operator.
if dog&.breed&.name
=> nil
Lastly, when the safe navigator is called on a method that doesn't exist or is false, an undefined method
error will pop up.
Drawbacks of using &.
So why not just slap on the operator everywhere? It can make code harder to read, particularly for those who are first starting out or coming from a different language. It may also obscure the intent of the code and can make it harder to debug. How do you know where this error is coming from? Is it because the dog doesn't exist or because the breed doesn't exist? It can also violate the Law of Demeter which tells us that it's not a great idea for a single function to know the structure of the whole system.
When to use &.
If you want to avoid setting up complicated if statements or &&
conditions, &.
is a more concise way to write the code and avoid nil errors. I found the safe navigation operator to be useful when exploring data from an API. It can also be useful when testing expressions without Ruby getting angry and being hit with a noMethodError
.