ruby哈希作为哈希的关键

时间:2011-02-22 08:09:34

标签: ruby hashmap ruby-1.8

在ruby 1.8.6中遇到以下奇怪的行为,在1.8.7中它似乎正常工作。有谁知道会造成什么?

h = {}
key_1 = {1 => 2}
key_2 = {1 => 2}
h[key_1] = 3
p key_1 == key_2 # => true
p h.has_key?(key_2) # => expect true, get false, wtf?

我原以为它是由哈希类上哈希方法的实现引起的。

p [key_1.hash, key_2.hash] # => [537787070, 537787060] (different)

但即使我重写Hash的哈希方法

class Hash
  def hash
    return self.keys.hash + self.values.hash
  end
end

p [key_1.hash, key_2.hash] # => [8,8] (same
p h.has_key?(key_2)        # => false

codepad链接到在线ruby 1.8.6解释器结果:http://codepad.org/7nCYMP4w

2 个答案:

答案 0 :(得分:2)

答案是因为在Ruby 1.8.6中,哈希编码算法被破解了。

http://paulbarry.com/articles/2009/09/14/why-rails-3-will-require-ruby-1-8-7

编辑:    这是一个示例,显示ruby不会在内部调用.hash:

 class Hash
    def hash
       raise
    end
 end

 {1=>1}.hash
 RuntimeError: 
from (irb):12:in `hash'
from (irb):17

 h = {1=>2}
 {1=>2}
 h[1]
 2

Ruby 1.8.6在这方面已经被打破,如果有一种纯Ruby的方式(例如打开Hash,人们会这样做。它已在1.8.7中修复

答案 1 :(得分:1)

这在1.8.7+中得到修复,但你也可以修补补丁1.8.6来做正确的事 例如: https://github.com/rdp/sane/blob/master/lib/sane/hash_hashes.rb