Comparing objects

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.

2006/5/5, Mark V. [email protected]:

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.

The most notable exception I am aware of is this:

irb(main):060:0> 2.eql? 2.0
=> false
irb(main):061:0> 2 == 2.0
=> true

A Hash uses eql?

HTH

robert

On May 5, 2006, at 4:44 PM, Robert K. wrote:

robert

Based on this I would amend your explanation with

#eql? – Equivalence with structure and type
#== – Equivalence with structure
#equal? – Identity

2006/5/5, Logan C. [email protected]:

A Hash uses eql?

HTH

robert

Based on this I would amend your explanation with

#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.)

Kind regards

robert

On 5/5/06, Robert K. [email protected] wrote:

#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.)

So why is it useful to have both == and eql?
Are there cases where you want them to behave differently?

On May 5, 2006, at 5:11 PM, Mark V. wrote:

=> true
#== – Equivalence with structure
Are there cases where you want them to behave differently?


R. Mark V.
Object Computing, Inc.

Well the post that sparked my response and “clarification” is one
such case.

2.eql? 2.0 is false, 2 == 2.0 is true

I imagine the major difference is == potentially calls coerce

I’d like to slightly restate the differences like:

#eql? – Equivalence with structure and type
#== – Equivalence with structure
#equal? – Identity

#eql? – Equivalence with type and value
#== – Equivalence with value
#equal? – Identity

On 5/6/06, Logan C. [email protected] wrote:

2.eql? 2.0 is false, 2 == 2.0 is true

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.