ruby 哈希作为哈希的关键

发布于 2024-10-18 07:23:58 字数 704 浏览 3 评论 0原文

在 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?

我本来以为是Hash类上实现了hash方法造成的。

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

但即使我覆盖哈希

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

键盘链接到在线 ruby​​ 1.8.6 解释器结果的哈希方法: http://codepad.org/ 7nCYMP4w

Came across the following weird behaviour in ruby 1.8.6, in 1.8.7 it seems to be working correctly. Does anyone know what would have caused this?

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?

I had thought that it would be caused by the implementation of the hash method on the Hash class.

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

but even if I override the hash method of 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 link to online ruby 1.8.6 interpreter results: http://codepad.org/7nCYMP4w

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不奢求什么 2024-10-25 07:23:58

答案是因为在 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 中已修复。

The answer is because in Ruby 1.8.6 the hash coding algorithm was broken for hash keys.

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

Edit:
Here is an example that shows that ruby does not call .hash internally:

 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 is broken in this respect, and if there were a pure Ruby way to do it (such as opening Hash, people would do it. It was fixed in 1.8.7

等风来 2024-10-25 07:23:58

这在 1.8.7+ 中得到了修复,但你也可以猴子补丁 1.8.6 来做到这一点
前任:
https://github.com/rdp/sane/blob/master /lib/sane/hash_hashes.rb

This is fixed in 1.8.7+ but you can monkey patch 1.8.6 to do it right, too
ex:
https://github.com/rdp/sane/blob/master/lib/sane/hash_hashes.rb

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文