On Sunday 06 March 2005 12:30 pm, Tom Willis wrote:
> Hi all,

Hi Tom!

> I want to use an object as a key in a Hash.
> class PointID
[...]
>   def hash
>     return [@x.object_id,@y.object_id].to_s
>   end
>   def ==(other)
>     return hash == other.hash
>   end
[...]
> end

You are very close.  In order to use an object as a hash key, it must support 
the hash function and the eql? (not ==) function.

The hash function should return an integer to be used for hashing.  Your 
version returns a string.  One correction might be ...

  def hash
    [@x.object_id, @y.object_id].to_s.hash
  end

That will now work.  But you probably really don't want to bother converting 
the above to a string.  Why not just do:

  def hash
    @x.object_id + @y.object_id
  end

The other issue is that hash uses eql? for comparisons rather than ==.  But 
eql? and == compare values, but == might attempt a type conversion before 
comparisons (e.g. 1 == 1.0 is true) while eql? will not (1.eql?(1.0) is 
false).  I would simply add:

  def eql?(other)
    self == other
  end

That should do it.

-- 
-- Jim Weirich    jim / weirichhouse.org     http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct, 
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)