In "Does `return` have precedence to certain operators in Ruby?" which I asked, Stefan explained in a comment that the or
and and
are actually control flow operators and should not be used as boolean operators (||
and &&
respectively).
He also referenced "Using “and” and “or” in Ruby":
and
and or
originate (like so much of Ruby) in Perl. In Perl, they were largely used to modify control flow, similar to the if
and unless
statement modifiers. (...)
They provide the following examples:
and
foo = 42 && foo / 2
This will be equivalent to:
foo = (42 && foo) / 2 # => NoMethodError: undefined method `/' for nil:NilClass
The goal is to assign a number to foo
and reassign it with half of its value. Thus the and
operator is useful here due to its low precedence, it modifies/controls what would be the normal flow of the individual expressions:
foo = 42 and foo / 2 # => 21
It can also be used as a reverse if
statement in a loop:
next if widget = widgets.pop
Which is equivalent to:
widget = widgets.pop and next
or
useful for chaining expressions together
If the first expression fails, execute the second one and so on:
foo = get_foo() or raise "Could not find foo!"
It can also be used as a:
reversed unless
statement modifier:
raise "Not ready!" unless ready_to_rock?
Which is equivalent to:
ready_to_rock? or raise "Not ready!"
Therefore as sawa explained the a or b
expression in:
return a or b
Has lower precedence than return a
which, when executed, escapes the current context and does not provide any value (void value). This then triggers the error (repl.it execution):
(repl):1: void value expression
puts return a or b
^~
This answer was made possible due to Stefan comments.