来自文档:http://ruby-doc.org/core-2.2.0/TrueClass.html#method-i-7C
true | puts("or")
true || puts("logical or")
# produces:
or
(仅限于TrueClass
上下文(不是Array
或Fixnum
上下文)
答案 0 :(得分:8)
很难说明为什么TrueClass
定义了#|
method。
它是方法的事实确实意味着它的两个"操作数"得到评估然后合并,这就是输出字符串"or"
的原因。双管是一个特殊的构造:如果第一个操作数是真的,它将不会计算第二个操作数。因此,作为一种进行布尔计算的方法,单个管道看起来没用。
现在,运算符在Fixnum
上更有意义:它执行与C,Java等相同的按位OR。
例如:
>> 133|243
=> 247
现在Java由于某种原因,将布尔值上的|
重载为非短路运算符。也许Ruby也在做我自己"? Ruby似乎不太可能想在这里复制Java。
因为
,情况更可能发生true | e
评估为
e
对于任何e,Ruby允许你将一堆真正的表达链接在一起。也许
true | e1 | e2 | e3 | e4
看起来比
更酷e1
e2
e3
e4
true
甚至
e1; e2; e3; e4; true
另一种可能性是它允许你将带有副作用的布尔生成表达式链接在一起。
f(x1) | f(x2) | f(x3) | f(x4)
并返回是否生成任何函数true
。这是一个人为的例子:
>> 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
当然,这仍然只是一种蹩脚的尝试,因为你会得到同样的效果:
>> [f(1),f(2),f(3),f(4)].any?
1
2
3
4
=> true
我怀疑,但我并非100%确定,运营商是否包含在某种"完整性"在代数意义上。布尔代数具有AND或OR,而||
实际上并不是具有热切评估语义的经典意义上的方法。所以也许因为这个原因而被抛出,并且,如果任何程序员碰巧找到它的用途,那么很棒。但是,在多年的编程中,我从未见过任何实用不短路的原因。
我实际上认为,如果有人在布尔上下文(即使用#|
)中编写依赖评估第二个参数的代码,那么这样的代码就会令人困惑 - 当然也不是参考透明,因为它会依赖副作用 - 因此应该重写。