From: "Michael C. Libby" Date: 2004-12-04T20:55:06+09:00 Subject: Re: Hash#eql? and Hash key testing On Sat, 2004-12-04 at 16:39 +0900, Joel VanderWerf wrote: > The ri docs for Object#eql? say: > > The +eql?+ method returns +true+ if _obj_ and _anObject_ have the > same value. Used by +Hash+ to test members for equality. > > However, the second sentence doesn't seem to be consistent with the > behavior of Hash (and Set): > > h1 = {1=>2, 3=>4} > h2 = {1=>2, 3=>4} > > p h1.eql?(h2) # ==> true > > h={h1=>true} > > p h[h1] # ==> true > p h[h2] # ==> nil > > Based on the docs, I would have expected > > p h[h2] # ==> true > > Have I misunderstood? h1 and h2 are not the same object above, though they are equivalent at the time you test for equality. h1 could get new elements, as could h2. mcl@saluki:~$ irb irb(main):001:0> a = {1=>2,3=>4} => {1=>2, 3=>4} irb(main):002:0> b = {1=>2,3=>4} => {1=>2, 3=>4} irb(main):003:0> a == b => true irb(main):004:0> a.__id__ == b.__id__ => false irb(main):005:0> c = {a=>true} => {{1=>2, 3=>4}=>true} irb(main):006:0> c[b] = 'foo' => "foo" irb(main):007:0> c => {{1=>2, 3=>4}=>"foo", {1=>2, 3=>4}=>true} irb(main):008:0> a[5]=6 => 6 irb(main):009:0> c => {{1=>2, 3=>4}=>"foo", {5=>6, 1=>2, 3=>4}=>true} irb(main):010:0> a == b => false With literals it's a different story: irb(main):011:0> x = 5 => 5 irb(main):012:0> y = 5 => 5 irb(main):013:0> x == y => true irb(main):015:0> c[x] = 'bar' => "bar" irb(main):016:0> c => {5=>"bar", {1=>2, 3=>4}=>"foo", {5=>6, 1=>2, 3=>4}=>true} irb(main):017:0> c[y] => "bar" irb(main):018:0> x.__id__ == y.__id__ => true -Michael C. Libby, www.andsoforth.com