The Safe Navigation Operator (&.) in Ruby

The Safe Navigation Operator (&.) in Ruby

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.