Safe Navigation Operator vs. Explicit Nil Check: Which is Better?

When writing Ruby code, one of the most common tasks is to handle potential nil values safely. Ruby provides a few ways to do this, and two approaches often come up: using the safe navigation operator(&.) and placing an explicit nil check first. In this post, we’ll compare both techniques and help you understand which one is best suited for your code.

The Safe Navigation Operator (&.)

Introduced in Ruby 2.3, the safe navigation operator (&.) allows you to call methods on an object only if that object is not nil. If the object is nil, the expression returns nil instead of throwing an error. This is especially useful when you’re unsure whether an object exists or is nil and want to avoid potential NoMethodError exceptions.

Here’s an example:

1
2
3
def hospitality_or_other?
  location_type&.hospitality? || location_type&.other? || location_type.nil?
end

In this example, the &. operator ensures that Ruby only attempts to call hospitality? or other? on location_type if it’s not nil. If location_type is nil, the condition returns nil, and Ruby evaluates the next part of the expression.

Explicit Nil Check

The explicit nil check, on the other hand, involves checking whether the object is nil before calling any methods on it. This approach is straightforward and works in all Ruby versions, regardless of whether you’re using Ruby 2.3 or later. It’s often seen as more “manual,” where you handle the nil check yourself.

Here’s how it looks:

1
2
3
def hospitality_or_other?
  location_type.nil? || location_type.hospitality? || location_type.other?
end

In this approach, we explicitly check if location_type is nil first. If it is, the method returns true immediately without attempting to call hospitality? or other?.

Comparing the Two Approaches

Let’s break down the differences between using the Safe Navigation Operator and an explicit nil check with a comparative table:

Aspect Safe Navigation (&.) Explicit Nil Check First
Simplicity More concise and compact. A bit more verbose, but still clear.
Readability Very readable and direct. Readable, but a little longer.
Efficiency Efficient; only checks nil once. May be slightly less efficient in longer conditions.
Clarity of Intention Less explicit, but still clear for Ruby users. Very explicit; shows intention of checking nil clearly.
Compatibility Requires Ruby 2.3+ Works in all Ruby versions.

Which Approach is Better?

In most cases, the Safe Navigation Operator (&.) is the better choice. Here’s why:

When Should You Use an Explicit Nil Check?

The explicit nil check can still be useful in certain scenarios:

For most Ruby developers working with Ruby 2.3 or later, the safe navigation operator (&.) is the better option. It’s more concise, modern, and efficient. However, if you’re working with an older Ruby version or if you prefer to be very explicit in your code, an explicit nil check still works just fine.

In general, it’s always good to choose the approach that best fits the context of your project and your team’s experience with Ruby. But for new projects or when working with modern versions of Ruby, using the &. operator is the recommended, more idiomatic choice.