## Short version or Reminder

Any subclass that overrides 'eql?' should also override 'hash'
appropriately.


## Long version

Probably all of us will agree that equality is very important... but it
will vary depending on what we are trying to compare.

In ruby we have different methods to compare objects... (==, ===, eql?,
equal?), and it is very important to know their differences.

The '==' is the 'daily used one' and in descendant subclasses.

https://ruby-doc.org/core-2.5.3/BasicObject.html#method-i-3D-3D

As described in the documentation subclasses, For objects of class
Object, 'eql?' is synonymous with '==' and subclasses normally
continue this tradition by aliasing 'eql?' to the overriden '==' method.

We have done this in different places in YaST (just look for
'alias_method :eql?, :==').

But in most of the cases we have omitted the 'hash' method override
which could be a problem in case we use Hashes or Arrays.

And this is basically what has happened in a recent bug where the user
had 16 interfaces configured and adding one more deleted
all his routes. (What? 16 is fine but 17 is not?)

https://ruby-doc.org/core-2.7.0/Array.html#method-i-2D
https://github.com/ruby/ruby/blob/master/array.c

Basically the 'difference' or '-' methods use 'eql?' for comparing
elements  when the array is smaller than 17 elements and the␣
'hash' when it is bigger.


Some Links:

- Recent bug https://bugzilla.suse.com/show_bug.cgi?id=1186082
-
https://github.com/yast/yast-storage-ng/pull/491/commits/1144a6ee3d88154f92f454d3c47013eed39cc494
- https://stevenharman.net/well-behaved-ruby-object-equality

-- 
Knut Alejandro Anderssen González
YaST Team at SUSE Linux GmbH

Reply via email to