# Comparing objects

**URL:** <https://www.ruby-forum.com/t/comparing-objects/59699>\
**Category:** Ruby\
**Created:** [May 5, 2006, 4:48pm UTC](https://www.ruby-forum.com/t/comparing-objects/59699 "2006-05-05T16:48:12Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![markcasio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@markcasio](https://www.ruby-forum.com/u/markcasio)\
**Post date:** [May 5, 2006, 4:48pm UTC](https://www.ruby-forum.com/t/comparing-objects/59699/1 "2006-05-05T16:48:12Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![markcasio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@markcasio](https://www.ruby-forum.com/u/markcasio)\
**Post date:** [May 5, 2006, 10:45pm UTC](https://www.ruby-forum.com/t/comparing-objects/59699/2 "2006-05-05T22:45:55Z")

</div>

2006/5/5, Mark V. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> 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

---

<div class="post-metadata">

**Author:** ![markcasio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@markcasio](https://www.ruby-forum.com/u/markcasio)\
**Post date:** [May 5, 2006, 10:52pm UTC](https://www.ruby-forum.com/t/comparing-objects/59699/3 "2006-05-05T22:52:02Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![markcasio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@markcasio](https://www.ruby-forum.com/u/markcasio)\
**Post date:** [May 5, 2006, 11:04pm UTC](https://www.ruby-forum.com/t/comparing-objects/59699/4 "2006-05-05T23:04:34Z")

</div>

2006/5/5, Logan C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

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

> **[Equivalence relation](https://en.wikipedia.org/wiki/Equivalence_relation)**
>
> All definitions tacitly require the homogeneous relation 
>   
> R
> R
>   
> be transitive: for all 
>   
>     
> a
> ,
> b
> ,
> c
> ,
>     
> a,b,c,
>   
> if 
>   
>     
>       
> a
> R
> b
>       
>     
> {\\displaystyle aRb}
>   
> and 
>   
>     
>       
> b
> R
> c
>       
>     
> {\\displaystyle bRc}
>   
> then 
>   
>     
>       
> a
> R
> c
> .
>       
>     
> {\\displaystyle aRc.}
>   
>  
> A term's definition may require additional...

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![markcasio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@markcasio](https://www.ruby-forum.com/u/markcasio)\
**Post date:** [May 5, 2006, 11:13pm UTC](https://www.ruby-forum.com/t/comparing-objects/59699/5 "2006-05-05T23:13:53Z")

</div>

On 5/5/06, Robert K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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?

---

<div class="post-metadata">

**Author:** ![markcasio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@markcasio](https://www.ruby-forum.com/u/markcasio)\
**Post date:** [May 6, 2006, 12:45am UTC](https://www.ruby-forum.com/t/comparing-objects/59699/6 "2006-05-06T00:45:58Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![markcasio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9bcb4/32.png) [@markcasio](https://www.ruby-forum.com/u/markcasio)\
**Post date:** [May 6, 2006, 12:25pm UTC](https://www.ruby-forum.com/t/comparing-objects/59699/7 "2006-05-06T12:25:01Z")

</div>

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. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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.
