11

I have a class Issue in which each class has a key field. Because keys are meant to be unique, I overrode the comparison operator such that two Issue objects are compared based on key like so:

def ==(other_issue)
  other_issue.key == @key
end

However, I am dealing with a case in which two there may be two variables referring to the same instance of an Issue, and thus a comparison by key would not distinguish between them. Is there any way I could check if the two variables refer to the same place?

scottysseus
  • 1,922
  • 3
  • 25
  • 50
  • 1
    Use `.equal?`: https://stackoverflow.com/questions/7156955/whats-the-difference-between-equal-eql-and – Ry- Jul 22 '15 at 18:50

2 Answers2

15

According to the source, the Object#equal? method should do what you're trying to do:

// From object.c
rb_obj_equal(VALUE obj1, VALUE obj2)
{
    if (obj1 == obj2) return Qtrue;
    return Qfalse;
}

So the ruby code you would write is:

obj1.equal?(obj2)
Zain Rizvi
  • 23,586
  • 22
  • 91
  • 133
fresskoma
  • 25,481
  • 10
  • 85
  • 128
  • Yes, .equal? was exactly what I needed. thank you also for the link to the source. – scottysseus Jul 23 '15 at 13:04
  • When I try this with identical active record objects, they don't return true. Is there a way to use `.equal?` on an Active Record object? – stevec May 22 '21 at 09:32
  • I'm not 100% sure how equality is defined in the confines of active record. I'd expect that two records are considered the same if they refer to the same database row (i.e. if their IDs are the same, most of the time). I think for this sort of check you want to use `==`, which is the same as `eql?` (not `equal?`). See also [this question](https://stackoverflow.com/questions/4738439/how-to-test-for-activerecord-object-equality). – fresskoma May 26 '21 at 18:56
-2

No, not really. And that is Good Thing™.

A basic tenet of object-orientation is that one object can simulate another object. If you could tell whether or not two objects are the same object ("Reference Equality"), then you could tell apart the simulation from the real thing, thus breaking object-orientation … which, for an object-oriented language like Ruby is not so good.

The default implementation of Object#equal? does indeed check for reference equality, but, just like every other method in Ruby, it can be overridden in subclasses or monkey-patched, so there is no way to guarantee that it will actually check for reference equality. And that is how it should be.

Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
  • 5
    The documentation of `equal?` explicitly states that it should not be overridden because it is use for object identity (in hashes and the like). Overriding `equal?` probably has severe side-effects. – fresskoma Jul 23 '15 at 09:37