1

The Ruby docs read as follows:

The eql? method returns true if obj and other refer to the same hash key.

So in order to use #eql? to compare two objects (or use objects as Hash keys), the object has to implement #hash in a meaningful manner.

How come the following happens?

class EqlTest
  def hash
    123
  end
end

a = EqlTest.new
b = EqlTest.new

a.hash == b.hash   # => true
a.eql? b           # => false

I could of course implement EqlTest#eql? but shouldn't the implementation inherited from Object be something along the lines of hash == other.hash already?

Thanks for your hints!

svoop
  • 3,318
  • 1
  • 23
  • 41
  • Does this answer your question? [What's the difference between equal?, eql?, ===, and ==?](https://stackoverflow.com/questions/7156955/whats-the-difference-between-equal-eql-and) – TonyArra Apr 15 '22 at 15:50

1 Answers1

1

This seems to be actually the other way around. eql? is expected to return true for objects returning the same hash value, but it is not defined to compare these values. You are simply expected to override both.

The eql? method returns true if obj and other refer to the same hash key. This is used by Hash to test members for equality. For any pair of objects where eql? returns true, the hash value of both objects must be equal. So any subclass that overrides eql? should also override hash appropriately.

BroiSatse
  • 44,031
  • 8
  • 61
  • 86
  • Additionally `Object#hash` documents state: "...This function must have the property that a.eql?(b) implies a.hash == b.hash..." reinforcing the need to override both. – engineersmnky Apr 15 '22 at 16:14