The main difference between the keywords is that the first |
is a method, and can be redefined for a class, and the second ||
is not, and can be never defined as a method, and just used for language syntax, as you can see in example below:
Array.new.respond_to?( :| )
# => true
Array.new.respond_to?( :|| )
SyntaxError: (irb):35: syntax error, unexpected tOP_ASGN, expecting tSTRING_CONTENT or tSTRING_DBEG or tSTRING_DVAR or tSTRING_END
So, when you have applied the #|
method it is able to return a value that differs from true
, or false
. Although for ruby's TrueClass
, and FalseClass
those values are true
or false
, but other descendants could redefine the return value, however, for Array
and Set
classes it implements functions similar to boolean bitwise operation. So can be sure that the true
or false
class's methods return also true
or false
. Otherwise, the keyword ||
is real language boolean operator, however it operates with values true, and not-true, you can see it on example:
'value1' || 'value2'
# => "value1"
true || false
# => true
'value1' || false
# => "value1"
false || 'value2'
# => "value2"
The return valus is always subordinated to logical expression, but the values of it are, as I denoted above, true, and not-true. Therefore you see in example return values not only of true/false
pair, but of the real variable values too, and you can use it as if
conditional operators as follows:
'value1' || 'value2'
and
if 'value1'
'value1'
else
'value2'
end
will return the same value.
According the or-equal assignment we see the following:
A |= false
# NameError: uninitialized constant A
a |= false
# false
A ||= false
# => false
In first case we are able to split |=
operation into the two: call to #|
method, and to assign the result to the variable. In the second case the ruby interpreter sees the whole operator ||=
, verifies weither it is nil
or undefined, and if yes assign to the variable or to the const the expression result.
The pair &
, &&
has the same explanation.