On 10/17/07, Paul Butcher <paul / texperts.com> wrote:

> Nobody has (yet) risen to the challenge at the end of my article, so I
> thought that I'd ask here :-)
>
> Just about every class in the standard library implements == and eql? as
> I describe in the article, i.e. eql? tests for equal values and == tests
> for "natural" equality (which normally means equal values).
...
>
> Hash, however, is an exception. Hash#== tests for equal values.
> Hash.eql?, however, tests for object identity:
...
> Why is hash the odd one out? I'm sure that there must be a good reason
> (Matz?) but I can't at the moment work out what it might be.
>
> I'd be very grateful for any light anyone could cast on this. Thanks!

Some clues:
irb(main):001:0> h1 = {:a => "1", :b => "2"}
=> {:b=>"2", :a=>"1"}
irb(main):002:0> h2 = {:a => "1", :b => "2"}
=> {:b=>"2", :a=>"1"}
irb(main):003:0> h1 == h2
=> true
irb(main):004:0> h1.eql? h2
=> false
irb(main):005:0> h1.hash
=> 19850
irb(main):006:0> h2.hash
=> 276530
irb(main):007:0> h1.object_id
=> 19850
irb(main):008:0> h2.object_id
=> 276530

I think the reason is twofold:

1) Using hashs as keys in another hash is not a common use case. I'm a
little hard-pressed to think of why I'd want to, although I'm famous
for lack of imagination.
2) Because of the requirement that obj1.eql? obj2 => obj1.hash ==
obj2.hash, implementing Hash#hash requires iterating over the keys and
values and would be fairly expensive and make accessing a hash with
hash keys by key impractical.


-- 
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/