&&, ||, and, or and safe navigation
Two sets of operators
Ruby has && and || with the precedence programmers expect, and and and or with a much lower precedence, lower than assignment. The second set exists for control flow, not for values, and mixing the two is a classic bug:
ruby -e 'x = true and false; puts x'
true
The line reads as (x = true) and false: the assignment happens first, so x is true and the false is thrown away. With && the same line is false:
ruby -e 'puts (true && false).inspect; puts (true and false).inspect'
false
false
Parentheses make both expressions evaluate to false; without them, only the && form assigns what the reader expects. Use && and || in expressions and keep and/or for a chain of statements, or drop them entirely.
The default with ||=
||= assigns only when the variable is nil or false. It is the short way to fill a default once, and it reads left to right:
ruby -e 'x = nil; x ||= 5; puts x'
5
A second x ||= 7 leaves the five alone. The pattern is common in a method that takes an optional argument, and it is also a trap with booleans: enabled ||= true turns a deliberate false into true, because false is falsy. For a boolean default, test nil? instead.
Safe navigation
&. calls a method only when the receiver is not nil; otherwise the whole expression is nil. It removes one level of if from a chain that may start with a missing value:
ruby -e 'x = nil; puts x&.length.inspect; puts "abc"&.length'
nil
3
The number of safe-navigation calls in a method is a measure of how uncertain the data is. A long a&.b&.c&.d chain usually means the first value should have been validated once, where it entered the program.
What to watch for
An &. chain returns
nil for a missing middle value, and a later
method without the ampersand raises. Keep the ampersands consistent for
the whole chain or the error appears at the step after the check.
&.length on a hash is not
hash[:length]. The ampersand goes before the dot,
so value&.[](:key) is the form for a
subscript, and it is rarely worth writing.
Next: Arrays
Article author: Arthur Isaev