While it might seem counterintuitive, you can use logical operators to determine whether or not a statement is run. For instance:
File.exist?(filename) or STDERR.puts "#{filename} does not exist!"
This will check to see if the file exists and only print the error message if it doesn't. The or
statement is lazy, which means it'll stop executing once it's sure which whether it's value is true or false. As soon as the first term is found to be true, there's no need to check the value of the other term. But if the first term is false, it must check the second term.
A common use is to set a default value:
glass = glass or 'full' # Optimist!
That sets the value of glass
to 'full' if it's not already set. More concisely, you can use the symbolic version of or
:
glass ||= 'empty' # Pessimist.
It's also possible to run the second statement only if the first one is false:
File.exist?(filename) and puts "#{filename} found!"
Again, and
is lazy so it will only execute the second statement if necessary to arrive at a value.
The or
operator has lower precedence than and
. Similarly, ||
has lower precedence than &&
. The symbol forms have higher precedence than the word forms. This is handy to know when you want to mix this technique with assignment:
a = 1 and b = 2
#=> a==1
#=> b==2
a = 1 && b = 2; puts a, b
#=> a==2
#=> b==2
Note that the Ruby Style Guide recommends:
The
and
andor
keywords are banned. The minimal added readability is just not worth the high probability of introducing subtle bugs. For boolean expressions, always use&&
and||
instead. For flow control, useif
andunless
;&&
and||
are also acceptable but less clear.