David A. Black在他的书中说:
[T] 条件赋值运算符
||=
,以及它很少见的表亲 &&=,两者都提供与伪运算符方法相同的快捷方式,但基于运算符,即||
and&&
,您无法覆盖。
为什么他特别提到我们不能覆盖||
and &&
?
与对象上的其他一些运算符不同,它们的行为在逻辑上取决于类,布尔运算符是语言的一部分。当你有一个运算符时,比如 , 说==
这个运算符的行为取决于对象的类型是合乎逻辑的。字符串应该逐个字符检查,Hash 键值元组逐个键值元组等。但是,&&
and的行为||
基于语言对真假的定义,而不是任何特定于对象的定义。如果语言允许您覆盖这些运算符,则可能没有一致的布尔模型,这些运算符将变得完全无用。
此外,还有性能方面的考虑。因为&&
和||
是短循环运算符,这意味着如果 的第一个参数&&
计算为假,则第二个参数甚至都不会被计算。对于||
,如果第一个计算结果为真,则第二个永远不会被计算。如果您可以覆盖这些运算符,则这种行为是不可能的,因为在 Ruby 中,运算符被重载为方法。根据定义,所有参数都必须在调用方法之前进行评估。因此,短路运算符的性能提升和编程便利性就丧失了。