提问人:illusionist 提问时间:8/23/2017 最后编辑:Danil Speranskyillusionist 更新时间:8/23/2017 访问量:171
覆盖 == 相等运算符仅在一个方向上起作用
Overriding == equality operator works only in one direction
问:
考虑下一个示例,其中我覆盖运算符以不断返回:==
true
class Example
def ==(other)
return true
end
end
但是,这仅在一个方向上起作用:
exp = Example.new
puts exp == {} #=> true
puts {} == exp #=> false
有没有办法迫使这种相等方法在相反的方向上工作?
答:
1赞
Danil Speransky
8/23/2017
#1
如果不更改其他类,这是不可能的。基本上等于.因此,如果你想让它工作,你需要覆盖第二个类的运算符。a == b
a.==(b)
==
1赞
Sergio Tulentsev
8/23/2017
#2
有没有办法迫使这种相等方法也向相反的方向工作?
不可以,但您可以更改以识别 的特殊情况。Hash#==
Example
class Example
def ==(other)
return true
end
end
class Hash
alias_method :original_double_equals, :==
def ==(other)
case other
when Example
other == self
else
original_double_equals(other)
end
end
end
exp = Example.new
exp == {} # => true
{} == exp # => true
{} == {} # => true
{foo: 1} == {foo: 2} # => false
如果我是你,我不会这样做。
评论
1赞
Simple Lime
8/23/2017
您也可以在重新定义方法之前为该方法添加别名:在示例中的第 7 行和第 8 行之间,然后调用 ...产生 、 、 作为输出==
alias :original_double_equals :"=="
super
original_double_equals(other)
true
true
true
false
0赞
Sergio Tulentsev
8/23/2017
@SimpleLime:实际上,这听起来确实是一个更好的主意。Lemme 这样做
1赞
Jörg W Mittag
8/23/2017
#3
不,这是不可能的。
Ruby 是一种面向对象的语言。OO 的基本思想是向对象和接收对象发送消息,只有接收对象才能决定如何响应该消息。
- 如果将消息发送到 object ,将 object 作为参数传递,则 and
a
可以单独决定如何响应。==
a
b
a
- 如果将消息发送到 object ,将 object 作为参数传递,则
b
可以单独决定如何响应。==
b
a
b
保证给出相同响应的唯一方法是,如果 and 合作并同意给出相同的响应。a
b
从理论上讲,可以设计一种语言,即不是将消息发送到 或 ,而是将消息发送到第三个“上下文对象”。IOW,不被解释为 or 而是 (例如,上下文对象可能只是你自己,即 )。在这种情况下,上下文对象可以访问两者的公共 API,并且可以采取措施确保它是可交换的。a == b
a
b
a == b
a.==(b)
b.==(a)
some_context_object.==(a, b)
self.==(a, b)
a
b
==
但总的来说,由于OO的基本性质,消息是不可交换的,接收对象是特殊的。
评论