Ruby’s safe navigation operator (&.
) is a nil-safe way to chain operations.
Let’s say we have a User
class, and that class can have first_name
and last_name
attributes:
me = User.new(first_name: "justin")
me.first_name # "justin"
me.first_name.upcase # "JUSTIN"
# We didn't give me a last_name
me.last_name # nil
me.last_name.upcase # NoMethodError: undefined method `upcase' for nil:NilClass
# using safe navigation, there's no error
me.last_name&.upcase # nil
# you could even chain further
me.last_name&.upcase&.downcase # nil
Without safe navigation, we’d need a more-verbose if
check to accomplish the same thing:
# same result as me.last_name&.upcase
if me.last_name
me.last_name.upcase
else
nil
end
If you’re familiar with Javascript, ruby’s safe navigation works just like javascript’s optional chaining1.
Note: &.
only works when dealing specifically with nil
, not false
(or any other falsy value):
me.last_name = false
me.last_name&.upcase # NoMethodError: undefined method `upcase' for false:FalseClass
- Javascript’s optional chaining actually handles two different falsey values,
null
andundefined
↩︎