Ruby hash as key to hash

The following strange behavior happened in ruby ​​1.8.6, in 1.8.7 it works correctly. Does anyone know what this would cause?

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 thought this would be caused by the implementation of the hash method in the Hash class.

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

but even if I override the Hash hash method

 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 

link to the code link to the online results of the Ruby 1.8.6 interpreter: http://codepad.org/7nCYMP4w

+4
source share
2 answers

The answer is that in Ruby 1.8.6, the hash encoding algorithm has been violated 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 inside:

  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 violated in this regard, and if it were a pure Ruby way (e.g. opening Hash ), it would do it. It was fixed in 1.8.7.

+2
source

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

+1
source

Source: https://habr.com/ru/post/1340753/


All Articles