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.

--
R. Mark Volkmann
Object Computing, Inc.

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

···

2006/5/5, Mark Volkmann <r.mark.volkmann@gmail.com>:

--
Have a look: Robert K. | Flickr

Based on this I would amend your explanation with

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

···

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

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

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

···

2006/5/5, Logan Capaldo <logancapaldo@gmail.com>:

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

> 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

Based on this I would amend your explanation with

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

--
Have a look: http://www.flickr.com/photos/fussel-foto/

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

···

On 5/5/06, Robert Klemme <shortcutter@googlemail.com> wrote:

2006/5/5, Logan Capaldo <logancapaldo@gmail.com>:
>
> On May 5, 2006, at 4:44 PM, Robert Klemme wrote:
>
> > 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
>
> 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.)

--
R. Mark Volkmann
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

···

On May 5, 2006, at 5:11 PM, Mark Volkmann wrote:

On 5/5/06, Robert Klemme <shortcutter@googlemail.com> wrote:

2006/5/5, Logan Capaldo <logancapaldo@gmail.com>:
>
> On May 5, 2006, at 4:44 PM, Robert Klemme wrote:
>
> > 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
>
> 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.)

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

--
R. Mark Volkmann
Object Computing, Inc.

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

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 Seo

···

On 5/6/06, Logan Capaldo <logancapaldo@gmail.com> wrote: