It is hard to tell why TrueClass
has a #|
method defined.
The fact that it is a method does mean that both of its "operands" get evaluated and then combined, which is why the string "or"
was output. The double pipe is a special construct: it will not evaluate the second operand if the first was truthy. Therefore, as a way to do boolean computations, the single pipe looks useless.
Now, the operator makes a lot more sense on Fixnum
: it performs the same bitwise OR as seen in C, Java, etc.
For example:
>> 133|243
=> 247
Now Java, for some reason, overloaded |
on booleans to be a non-short circuit operator. Perhaps Ruby is doing a "me too"? Doesn't seem likely that Ruby would want to copy Java here.
It's more likely the case that because
true | e
evaluates to
e
for any e, Ruby is allowing you to chain together a bunch of truthy expressions. Perhaps
true | e1 | e2 | e3 | e4
looks cooler than
e1
e2
e3
e4
true
or even
e1; e2; e3; e4; true
Another possibility might be that it allows you to chain together boolean-producing expressions with side-effects.
f(x1) | f(x2) | f(x3) | f(x4)
and return whether or not any of the functions produced true
. Here's a contrived example:
>> def f(x);puts x;return x==2;end
=> :f
>> f(1) || f(2) || f(3) || f(4)
1
2
=> true
>> f(1) | f(2) | f(3) | f(4)
1
2
3
4
=> true
Of course, this is still just a lame attempt because you get the same effect with:
>> [f(1),f(2),f(3),f(4)].any?
1
2
3
4
=> true
I suspect, but am not 100% sure, that the operator is included for some kind of "completeness" in the algebraic sense. Boolean algebra has AND or OR, and the ||
isn't really a method in the classic sense of having eager evaluation semantics. So maybe it was thrown in because of that reason, and, if any programmer happens to find a use for it, then wonderful. But I've never seen, in many years of programming, any pragmatic reason for not short-circuiting.
I would in fact argue that if someone were to write code that depended on the evaluation of the second argument in a boolean context (i.e., using #|
), that such code would be confusing --- and certainly not referentially transparent, as it would rely on side effects --- and should therefore be rewritten.