On 5/21/21 2:55 PM, Knut Alejandro Anderssen González wrote:
## Short version or Reminder
Any subclass that overrides 'eql?' should also override 'hash' appropriately.
By default, the methods #==, #eql? and #equal? in Object subclasses return true if both objects are the same (point to the same object in memory). Well, actually #eql? should return true if both objects refer to the same hash key. But in practice, two objects have the same hash key if they are the very same object. There are some exceptions like String, which returns the same hash key if they have the same value. The #eql? and #hash methods must be related. That is, if two objects are #eql?, then they should have the same #hash. This is important, otherwise we could have unexpected results in certain operations like subtracting Arrays. When performing the difference of two Arrays, the method used for comparing the objects in the Array depends on the Array length (see source code of Array#difference [1]). If both Arrays have more than SMALL_ARRAY_LEN (i.e., 16) elements, then the #hash method is used. Otherwise it uses #eql?. This is one of the reason why #eql? and #hash should be paired. In YaST code, we tend to overload #== and then to make #eql? an alias to the overloaded #==. This is dangerous if we forget to modify #hash properly. For example, the result of Array<OurClass> - Array<OurClass> would depend on the length of the arrays. To avoid these problems, I think we should keep the same logic for #eql? and #hash. And optionally, we could do #== an alias to #eql?. I have prepared a proposal in yast-users [2]. It consists on a mixing to implement the "Equatable" property. What do you think? If you agree with this solution (or something) similar, then we could move it to a more generic place like yast2 repo. Regards, Iván [1] https://ruby-doc.org/core-2.7.0/Array.html#method-i-difference [2] https://github.com/yast/yast-users/pull/283/files -- José Iván López González YaST Team at SUSE LINUX GmbH IRC: jilopez