Ruby Language Control flow with logic statements


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 and or 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, use if and unless; && and || are also acceptable but less clear.