Akinori MUSHA wrote ...


> D'oh, I was confused.  I meant (a.hash == b.hash => a.eql?(b)) i.e.

Boy, do I know this feeling;-)

> (!a.eql?(b) => a.hash != b.hash).
> 
> And the following test is an irrelevant requirement anyway:

I added the test below since I (wrongly) assumed that it
would  catch a bug of your eql? implementation.  I forgot
that Hash's hash is content based (actually I knew better
but then I was being my usual confused self). 

Since  Hash::hash  is strictly ``id'' based it seems 
to me that using the id of the instance variable @hash 

  def hash
     @hash.hash
  end

is pretty much equivalent to not defining a Set::hash
method at all (in other words Set::hash == Set::id).
In your previous email you voiced serious doubt 
over the usefulness (and computational feasibility)
of a contend based hash method like

   def hash
      inject(size*size) {|sum,e| sum+=e.hash }
   end.

However don't forget this is exactly how the Array hash 
method is the defined, the only (main) difference being
that the latter is sensitive to the element order. Also
if the Set::hash method is not content sensitive
it essentially makes no sense to talk about 
Sets of Sets, like a partition of a given Set.

For example, right now

 Set[Set[1,2],Set[3,4]] != Set[Set[1,2],Set[3,4]]

   	
> 
> > > +    def test_eql?
> > > +       a = EqlClass.new
> > > +       b = EqlClass.new until b.hash == a.hash
> > > +       assert !(Set[a].eql?(Set[b]))
> > > +    end
>
> I think x.eql?(y) does not need to be false for any given x and y.  It
> is certainly not preferable but the following definition of a class is
> possible and legal:
> 
> 	class Foo
> 	  def hash
> 	    1
> 	  end
> 
> 	  def eql?()
> 	    true
> 	  end
> 	end
> 
> Am I missing something?

Not that I know off ...


/Christoph