In most cases == and eql? have the same result. In some cases, eql? is more strict than == :
42.0 == 42 # => true 42.0.eql?(42) # => false
Because of this, if you define == , you probably want to define eql? as well eql? (or vice versa).
eql? assumption been made that the Hash class will use eql? to distinguish between different keys, not == . It could be == , mind you, but eql? was cleaner.
To avoid costly eql? calls eql? all the time, the value of the hash function is calculated with the requirement that two eql? must have the same hash value. This hash value is stored, which makes searching in the future very simple: if the hash code does not match, then the values are not eql? ...
For this reason, should you define Hash reasonable way if you define eql? .
Note that calculating a hash value is almost always more expensive than comparing with == or eql? . However, if the hash is calculated, checking if the hashes match is very fast.
Because hashes usually involve a lot of comparisons, a relatively expensive hash calculation is done once for each key, and then once for each search. Imagine a hash with 10 inputs. It will take 10 Hash calls to create it before the first search is completed. The first search will be relatively quick: a single Hash call, followed by a very efficient hash code comparison (this is actually faster than this, as they are “indexed”). If there is a match, do you still need to call eql? to ensure real fit. Really, two objects which are not eql? can have the same hash. The only guarantee is that there are two eql? must have the same hash, but two different objects can have the same value.
If you want to do the same with Array , you may need 10 eql? calls eql? for every search.
Why is it worth it, I don’t think that the ruby primer you are referring to is as clear as possible. He neglects the fact that calculating Hash can be expensive, so this is only done when it makes sense, i.e. When it is a good assumption that each element will be compared many times. Moreover, it is a shame that an example of custom eql? which it gives uses == to compare instance variables. Ideally would he use eql? for consistency, just like arrays == if its elements == , and arrays eql? if its elements are eql? . Finally, is it really worth mentioning Struct , which defines decent == , Hash and eql? for you.