From: Charles Mills Date: 2004-08-06T23:08:47+09:00 Subject: Re: Sets are not extensional On Aug 6, 2004, at 3:11 AM, Robert Klemme wrote: > > "Charles Mills" schrieb im Newsbeitrag > news:2B60D928-E751-11D8-AF77-000A95A27A10@freeshell.org... >> >> On Aug 5, 2004, at 6:41 PM, George Ogata wrote: >> >>> Kristof Bastiaensen writes: >>> >>>> {}.hash == {}.hash >>>> => false >>>> Set[].hash == Set[].hash >>>> => false >>>> [].hash == [].hash >>>> => true >>>> >>>> I have no idea for the reason why different hashes have different >>>> hashvalues, while different arrays may get the same value (based on >>>> the >>>> contents of the array). >>> >>> This seems like a blatant bug to me. `a.eql? b' must imply `a.hash >>> == >>> b.hash', yet: > > Yes, this issue has come up before IIRC. Maybe Matz did something > about > this but it's not included in a release version. > >> I agree: >>> a = {} #=> {} >>> a.hash #=> 1650134 >>> a.id #=> 1650134 >>> b = {} #=> {} >>> b.hash #=> 1639814 >> # So hash on an empty hash returns the objects id.... >>> a = {"a"=>"b"} #=> {"a"=>"b"} >>> a.hash #=> 1682094 >>> a.clear #=> {} >>> a.hash #=> 1682094 >> # Looks like no two hashes hash to one another... >> # Here is the reason >> /* in object.c */ >> rb_mKernel = rb_define_module("Kernel"); >> rb_include_module(rb_cObject, rb_mKernel); >> /* ..snip.. */ >> rb_define_method(rb_mKernel, "object_id", rb_obj_id, 0); /* I intended to show this line: */ rb_define_method(rb_mKernel, "hash", rb_obj_id, 0); Anyway, so the code above shows class Object including module Kernel. Module Kernel defines "hash" as rb_obj_id(). So Object gets rb_obj_id() as its "hash" method. >> >> /* in hash.c the "hash" method is never overridden. So rb_obj_id() is >> the "hash" method for hashes. */ > > Where do you take that conclusion from? From the source quotes you > name, > there is no indication of a connection between #hash and #id. And > you're > showing code for Kernel which is unrelated to this thread. The only > conclusion so far is, that Hash#hash is Object#hash (because it's not > overridden as you state) and thus can't take into account the contents > of > the Hash. Can you please clarify this? Don't forget you can always look at the source yourself :) -Charlie