From: Rick DeNatale Date: 2007-10-17T21:12:26+09:00 Subject: Re: equal? versus eql? versus == versus === verus <=> On 10/17/07, Paul Butcher 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/