Override `#hash` when overriding `#eql?`
In my notes here, I’ve written that
#hash must be overridden when overriding
#eql?. I was unsure why this was the case.
I see in pry that all objects respond to
> 1.hash => 3748939910403886956 > 'a'.hash => 1677925148165319732 > [1,2,3].hash => -2230614089907012012 > Time.now.hash => -2249667312364590389
Equal objects return the same value:
> 1 == 1 => true > 1.hash => 3748939910403886956 > 1.hash => 3748939910403886956
Hash comes from the
> 1.method(:hash).owner => Kernel
The Kernel module is included by class Object, so its methods are available in every Ruby object.
It’s basically a bunch of helper methods made available to every class.
Kernel#hash seems to be undocumented though. It’s not in in the docs for the
Kernel module. Though, that page does point towards the
Object class page for information on
Kernel instance methods. But there’s nothing on it there either.
The explanation to why
#hash needs to be overridden when
#eql is changed is in the
Two objects refer to the same hash key when their hash value is identical and the two objects are eql? to each other.
Two objects can have the same hash value but be unequal however this would be detriment to the speed of the hash.
So when keying by multiple objects, so long as their
eql? values match, they will point to the same bucket.