Reputation: 2396
I have a problem with "hash" method from ruby: http://apidock.com/ruby/v1_8_7_330/Hash/hash
I use this to compare two different objects with the same content to find collisions between data base objects and new elements with the same attributes.
It has been apparently working for a long time (more than one year) but it has suddenly stopped working in my dev computer.
If I try this in the rails console:
a = {:a => 'a', :b=>'b'}
b = {:a => 'a', :b=>'b'}
a.hash
b.hash
I get the same value for both a.hash and b.hash (-3820017043059270405
) in the same console. The problem is, if I change to another console it returns a different value from the first console (-1865824882785682267
).
Shouldn't it be returning the same hash ever?
Thanks in advance.
Edit: It worked good in production because of ree 1.8.7 version.
Upvotes: 8
Views: 1415
Reputation: 27207
From: http://ruby-doc.org/core-2.0/Object.html#method-i-hash
The hash value for an object may not be identical across invocations or implementations of ruby. If you need a stable identifier across ruby invocations and implementations you will need to generate one with a custom method.
Although this is documentation from Ruby 2.0, I believe this has been the case for a while - i.e. you are not guaranteed in general that Ruby objects that are equivalent using .eql? will have the same hash value computed in different Ruby processes.
When you call Hash.hash, my understanding is that this returns a combination of hash values calculated from the objects used as keys and values in the hash object, and thus is subject to the same documentation.
Upvotes: 2
Reputation: 86
No, it should not!
Different Ruby implementations (like jRuby, Rubinius, MRI 1.8.x, MRI 1.9.x etc) are using different ways to generate hashes. For example, for some objects (like you own classes or Hash instances) runtime will assign uniq and random id while creating this object. If I am not wrong, MRI tight works with hashes based on memory addresses: http://rxr.whitequark.org/mri/source/gc.c?v=1.8.7-p370#2111
So you can not guarantee that every run of your code will use the same random values or the same memory addresses every time.
Also I suggest to use ruby-doc instead of apidock for Ruby internals: http://ruby-doc.org/core-2.0/Object.html#method-i-hash
The hash value for an object may not be identical across invocations or implementations of ruby. If you need a stable identifier across ruby invocations and implementations you will need to generate one with a custom method.
Hope it will help you!
Upvotes: 7