ruby 哈希作为哈希的关键
在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
答案是因为在 Ruby 1.8.6 中,哈希键的哈希编码算法被破坏了。
http://paulbarry .com/articles/2009/09/14/why-rails-3-will-require-ruby-1-8-7
编辑:
下面是一个例子,表明 ruby 内部不调用 .hash:
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:
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这在 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