Hi, was playing around with an idea after reading the thread about defining
#hash. My understanding was that #hash gives a unique identifier, and that
#eql? allows the hash to determine whether the two objects are equal in
terms of being the same hash key. So I wrote some code that should take an
equivalent instance, or a string for quick access. But it behaves in a way
that I completely don't understand. Hoping someone can help:
User = Struct.new :name, :age, :identifier do
def hash
name.hash
end
def eql?(other)
puts "#{name} was asked if they were equal to #{other.inspect}"
(other == name) || (other.name == name && other.age == age)
end
end
josh = User.new 'Josh', 28, 'first Josh'
hash = {josh => josh}
hash[josh] # => #<struct User name="Josh",
age=28, identifier="first Josh">
hash[User.new 'Josh', 28, 'second Josh'] # => #<struct User name="Josh",
age=28, identifier="first Josh">
hash['Josh'] # => nil
# >> Josh was asked if they were equal to #<struct User name="Josh",
age=28, identifier="first Josh">
So I would have expected all three to go through eql? Instead, we see that
only the case where the key was the same object goes through. However, it
identifies that the second Josh is the same key, without invoking User#eql?
How does it do this?
And why does the string "Josh" not find the instance?
This is all probably in my copy of the Pickaxe, but it's in Chicago and I'm
out of town