How to Use Safe Navigation in Ruby
The Ruby Safe Navigation operator(&.
) was introduced in Ruby 2.3.0. It allows you to chain methods on an object safely, basically to avoid the popular undefined method for nil:NilClass
error.
This article will shortly discuss how to use safe navigation in Ruby.
Use Safe Navigation to Prevent undefined method
in Ruby
Example Code:
class Bus
def seats
14
end
end
class Vehicle
def initialize(name)
@name = name
end
def category
Bus.new if @name == 'hiace'
end
end
vehicle = Vehicle.new('camry')
number_of_seats = vehicle.category.seats
puts number_of_seats
Output:
undefined method `seats' for nil:NilClass (NoMethodError)
As seen in the above example, vehicle.category.seats
exploded and resulted in an undefined method
error because vehicle.category
already returns a nil
. To avoid this issue, we need to check if the vehicle.category
is successful before chaining another method.
The next example, vehicle.category && vehicle.category.seats
means if vehicle.category
is successful, then vehicle.category.seats
should be evaluated, else the code execution should stop and return nil
. This works well but can be written with the Safe Navigation Operator.
Example Code:
class Bus
def seats
14
end
end
class Vehicle
def initialize(name)
@name = name
end
def category
Bus.new if @name == 'hiace'
end
end
vehicle = Vehicle.new('camry')
number_of_seats = vehicle.category && vehicle.category.seats
puts number_of_seats
Output:
nil
In this last example, we’ll use another version of Safe Navigation that is more readable and concise. It becomes useful in situations where we have to chain many methods on an object, e.g object1&.method1&.method2&.method3&.method4
.
Example Code:
class Bus
def seats
14
end
end
class Vehicle
def initialize(name)
@name = name
end
def category
Bus.new if @name == 'hiace'
end
end
vehicle = Vehicle.new('camry')
number_of_seats = vehicle&.category&.seats
puts number_of_seats
Output:
nil