1. The safe navigation operator
There are some languages that support object-oriented programming that have support for the so-called
the safe navigation operator (SNO). Also it's known as optional chaining operator, safe call operator or null-conditional operator. The SNO is a binary operator that returns null if its first argument is null;
otherwise it returns the second argument.
It's used to avoid sequential explicit null checks and assignments and replace them with method/property chaining. In programming languages where the navigation operator (e.g. ".") leads to an error if applied to a null object, the safe navigation operator stops the evaluation of a method/field chain and returns null as the value of the chain expression. It's currently supported in languages such as Apache Groovy, Ruby, Swift, C#, Kotlin, CoffeeScript and others. There is currently no common naming convention for this operator, but SNO is the most widely used term.
The main advantage of using this operator is that it solves a problem commonly known as pyramid of doom. Instead of writing multiple nested ifs, programmers can just use usual chaining, but put question mark symbols before dots (or other characters used for chaining).
Ruby supports the
&. safe navigation operator (also known as the lonely operator) since version 2.3.0
Let's consider concrete example of using
safe navigation operator on Ruby. My current version of Ruby is 2.5.1
Let's say that we have two classes: Owner and Account:
class Owner
attr_accessor :first_name, :last_name, :age
def initialize(first_name:, last_name:, age:)
self.first_name = first_name
self.last_name = last_name
self.age = age
end
def summary
"Owner: first name: #{first_name}, last name: #{last_name}, age: #{age}"
end
end
module Roles
GUEST = 1
USER = 2
ADMIN = 4
end
class Account
include Roles
attr_accessor :owner, :role
def initialize(owner, role = GUEST)
self.owner = owner
self.role = role
end
end
Create instances of these classes like that
owner = Owner.new(
first_name: 'John',
last_name: 'Smith',
age: 30
)
account = Account.new(owner, Roles::USER)
Now we can get a full information about owner from account by the following way
puts account.owner.summary
But what if, while creating instances of our classes, something goes wrong? Then when you try to get the full information about owner from account you won't have guarantees that this operation will be successful. Moreover, we can get an error and our system may fall. Here is an example of such a situation
account = Account.new(nil)
puts account.owner.summary
As result we get next error:
undefined method `summary' for nil:NilClass (NoMethodError)
So, to avoid this, you can use safe navigation operator
&.
puts account&.owner&.summary
And instead of an error, we get nil (it's a null in Ruby)
2. The null coalescing operator
The null coalescing operator (called the Logical Defined-Or operator in Perl) is a binary operator that is part of the syntax for a basic conditional expression in several programming languages. While its behavior differs between implementations, the null coalescing operator generally returns the result of its first operand if it exists and isn't null.
In contrast to the ternary conditional if operator used as x ? x : y, but like the binary Elvis operator used as x ?: y, the null coalescing operator is a binary operator and thus evaluates its operands at most once, which is significant if the evaluation of x has side-effects.
In the ruby for these purposes, we can use the operator
||
some_variable = nil || 'default_value'