最小的测试用例:
class C
def hash
3
end
end
[C.new, C.new].uniq
=> [#<C:0x00000003a05098>, #<C:0x00000003a05070>]
Run Code Online (Sandbox Code Playgroud)
根据1.9.3 Array#uniq docs,它应该删除重复项.在源代码中,它从数组创建哈希,循环哈希,并将每个哈希值添加到新数组中以返回.这个类C为所有对象返回相同的哈希键(你可以看到它通过puts在那里抛出来调用它),但返回的数组uniq没有重复数据删除.
是否有更多的定义uniq?==对于物品来说,这绝对不是真的.
Array#uniq依赖于两者hash并eql?进行比较:
class C
def hash
3
end
def eql?( c )
self.hash == c.hash
end
end
[C.new, C.new].uniq # #<C:0x00000000c70498>
Run Code Online (Sandbox Code Playgroud)
注意:如果你要超载eql?那么你也应该超载==.插入类定义:
alias :== :eql?
Run Code Online (Sandbox Code Playgroud)
然后按预期评估:
C.new == C.new # => true
Run Code Online (Sandbox Code Playgroud)