匹配哈希,eql?返回true,但是has_key?返回false

时间:2015-04-19 11:03:36

标签: ruby hashmap

我在Ruby 2.2.1上有以下情况:

a = ... # some object
h = ... # some hash

p h.size #=> 1
p h.keys.first.hash == a.hash #=> true
p h.keys.first.eql?(a) #=> true
p h.has_key?(a) #=> false

这怎么可能?我认为哈希匹配和eql?返回true是键被认为是相等的唯一条件。

<小时/> 修改:这是完整的计划。但请注意我不会问如何修复它 - 我知道如何。 我在问为什么Ruby会这样做!因为我很困惑为什么Hash的API合同在这种情况下无效。

class A
  attr_reader :x

  def initialize(x)
    @x = x
  end

  MY_HASH = { A.new(5) => 'foo' }

  def ==(other)
    @x == other.x
  end

  alias_method :eql?, :==

  def hash
    @x
  end
end

a = A.new(5)
h = A::MY_HASH

p h.size #=> 1
p h.keys.first.hash == a.hash #=> true
p h.keys.first.eql?(a) #=> true
p h.has_key?(a) #=> false

1 个答案:

答案 0 :(得分:3)

在您创建MY_HASH时,hash的新A函数尚未定义,因此MY_HASH在创建其值的索引时将使用默认值MY_HASH 。稍后定义新的哈希函数时,它将更改对象的散列方式但不会自动更新已存在的哈希MY_HASH中的索引。

在为课程hash定义新的A方法或运行MY_HASH.rehash

之后,您解决了我的初始化问题p h.has_key?(a) #=> false A::MY_HASH.rehash p h.has_key?(a) #=> true
{{1}}