Comparing objects in Ruby can be a little confusing. Let me know if
I’ve got this straight.
eql?
determines whether two object references refer to objects that
have the same “value”
for example, my_car.eql?(your_car)
could test whether my car and your car have the same make, model and
year
need to override this method in the Car class to be meaningful,
otherwise it’s the same as ==
equal?
determines whether two object references refer to the same object in
memory
(have the same object id)
for example, my_car.equal?(your_car)
tests whether we share the same car
==
sometimes same as equal?, but sometimes different
for example, mixing in the Comparable module changes it to be based
on
<=> which would be overridden
I kind of wish that “eql?” was named “same_value” and “equal?” was
named “same_object?” so it would be easier to remember. Using “==”
seems somewhat dangerous unless you’re working with built-in types or
types that you know mixin Comparable. Otherwise there is some
uncertainty about what it does without looking at the code of the
classes being compared.
Comparing objects in Ruby can be a little confusing. Let me know if
I’ve got this straight.
eql?
determines whether two object references refer to objects that
have the same “value”
for example, my_car.eql?(your_car)
could test whether my car and your car have the same make, model and year
need to override this method in the Car class to be meaningful,
otherwise it’s the same as ==
This is called “equivalence”.
equal?
determines whether two object references refer to the same object in memory
(have the same object id)
for example, my_car.equal?(your_car)
tests whether we share the same car
This is called “identity”.
==
sometimes same as equal?, but sometimes different
for example, mixing in the Comparable module changes it to be based on
<=> which would be overridden
This again is “equivalence”.
I kind of wish that “eql?” was named “same_value” and “equal?” was
named “same_object?” so it would be easier to remember. Using “==”
seems somewhat dangerous unless you’re working with built-in types or
types that you know mixin Comparable. Otherwise there is some
uncertainty about what it does without looking at the code of the
classes being compared.
#eql? – Equivalence with structure and type
#== – Equivalence with structure #equal? – Identity
I’d leave it at “equivalence” for == and eql? because for most types
they behave the same. Basically every class’s author is free what she
considers “equivalence”. Equivalence is a mathematical term with clear
cut meaning and all implementations that satisfy these criteria are
compatible with the std lib (Hash, Enumerable methods etc.)
I’d leave it at “equivalence” for == and eql? because for most types
they behave the same. Basically every class’s author is free what she
considers “equivalence”. Equivalence is a mathematical term with clear
cut meaning and all implementations that satisfy these criteria are
compatible with the std lib (Hash, Enumerable methods etc.)
So why is it useful to have both == and eql?
Are there cases where you want them to behave differently?
I imagine the major difference is == potentially calls coerce
I’d like to interpret calling coerce as a comparison based on values
while ignoring types. Hence, 2.eql? 2.0 is false because their type is
differnt,
while 2 == 2.0 is true because their value is the same though their have
differnt
types.
Sincerely,
Minkoo S.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.