EQL? 重新定义Object#hash后的行为
Ruby API说:
eql? 方法返回true如果obj和其他引用相同的散列键。
我改变了Object
的哈希方法:
class Object
def hash
1
end
end
Object.new.hash == Object.new.hash
# => true
Object.new.eql? Object.new
# => false
我不明白为什么第二个陈述返回false
; 根据上面的Ruby Object API,它应该返回true
。
这是一个文档错误。 你读得对,但文件是矛盾的。
一方面,文件说:
eql? 方法返回true如果obj和其他引用相同的散列键。
从中你可以期待你的问题:
Object.new.eql? Object.new
# => true
另一方面,它也说:
对于Object类的对象,eql? 与==同义。
==
的定义如下给出:
在Object级别,==只有在obj和其他对象相同时才返回true。
它在逻辑上遵循:
对于Object类的对象,eql? 仅当obj和其他对象相同时才返回true。
您应该从中期望:
Object.new.eql? Object.new
# => false
所以文件做出矛盾的说法。 你依靠其中一个,并作出了期望,但看看实际结果,现实似乎支持第二个要求。
这不是文档所说的,“相同的哈希键”与您发布的代码并不真正相关。
hash
会创建一个哈希键,其含义是a.eql?(b)
表示a.hash == b.hash
。 这不同于打破hash
和期待未经修改的eql?
以您期望的方式工作。
eql?
必须重写以提供所需的语义,例如,自定义类可以覆盖eql?
提供特定领域的等同性。 如果您希望其他代码正常工作,上述hash
合同影响仍需要遵循。
(如果你覆盖equals
,这与Java口头禅重写hashCode
类似,例如http://www.xyzws.com/javafaq/why-always-override-hashcode-if-overriding-equals/20。)。
您正在创建两个新对象,它们永远不会相同。
a = Object.new
=> #<Object:0x007fd16b35c8b8>
b = Object.new
=> #<Object:0x007fd16b355540>
我会把你推荐给这个SO问题
链接地址: http://www.djcxy.com/p/58487.html