On Sun, March 6, 2005 5:30 pm, Tom Willis said:
> Hi all,
>
> I didn't want my first bit of participation on this list to be
> something this silly. But I'm afraid I missed something vital in my 48
> hour crash course.
>
> If someone could take 10 seconds and tell me what I'm doing wrong I'd
> greatly appreciate it and will give you props in my epitaph.
>
> Feel free to point out and make fun of the style too :) I have thick skin.
>
> I want to use an object as a key in a Hash.
>
>
> here's some example code...
>
> def main
>   puts "running this script..."
>   testpointid
> end
>
> def testpointid
>   p = PointID.new(1,1)
>   p2 = PointID.new(1,2)
>   pdup = PointID.new(1,1)
>   print "p!=pdup\n" if p!=pdup
>   d = Hash.new()
>   d[p]="point1"
>   d[p2]="point2"
>
>   #both of these return nil and I don't understand why
>   print "PointID test failed" if d[p]!="point1"
>   print "PointID test failed" if d[pdup]!="point1"
>
>   #this works, but it's not quite the interface I want
>   d[p.hash]="point1"
>   d[p2.hash]="point2"
>
>
>   print "PointID test failed" if d[p.hash]!="point1"
>   print "PointID test failed" if d[pdup.hash]!="point1"
>
>
> end
>
> class PointID
>   attr_reader :x,:y
>
>   def initialize(x,y)
>     @x = x
>     @y = y
>     @x.freeze
>     @y.freeze
>
>   end
>
>   def hash
>     return [@x.object_id,@y.object_id].to_s
>   end
>
>   def ==(other)
>     return hash == other.hash
>   end
>
>   def to_s
>     return hash()
>   end
>
> end

Hash normally goes by object equality; i.e. whether the reference
points to the same object. Your #hash generates a string from the
two values, but the crux is that it's a String that it returns so
I think object-equality is used for comparisons. Try to have your
#hash return ...to_s.hash instead, and see what happens.

Generally speaking, using an object this way might not be the best
idea. If each Point were an immutable, unique instance (think Fixnum,
for example), I would think it's OK but I'm somewhat leery of this.
Maybe use the direct coordinates instead -or then make each Point
unique (and then you'd have a RefToPoint that would be used in making
shapes, for example).

What effect do you want?

> Thomas G. Willis

E