Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ruby typical eql? and == implementations

I've been reading about the differences between eql? and == in ruby, and I understand that == compares the values while eql? compares the value and the type

According to the ruby docs:

For objects of class Object, eql? is synonymous with ==. Subclasses normally continue this tradition, but there are exceptions.

It does not seem like the behavior specified in the docs is automatically inherited, but rather this is just a suggestion of how to implement these methods. Does this also imply that if you override either == or eql? then you should override both?

In the class Person below, is this the typical way of overridding eql? and ==, where the less restrictive == just delegates to the more restrictive eql? (it would seem backwards to have eql? delegate to == if == was only implemented to compare values and not types).

class Person

  def initialize(name) 
    @name = name
  end

  def eql?(other)
    other.instance_of?(self.class) && @name == other.name
  end

  def ==(other)
    self.eql?(other)
  end

protected
    attr_reader :name

end
like image 445
Jeff Storey Avatar asked Jun 28 '12 02:06

Jeff Storey


1 Answers

I get the confusion now, what the docs meant by aliasing the eql? and == methods are implemented like this:

class Test
  def foo
    "foo"
  end
  alias_method :bar, :foo
end

baz = Test.new
baz.foo #=> foo
baz.bar #=> foo

#override method bar
class Test
  def bar
    "bbq!"
  end
end

baz = Test.new
baz.foo #=> foo
baz.bar #=> bbq!

So that's why when you override ==, it doesn't affect eql? even though they're 'synonymous'. So in your case, it should be:

class Person
  #...
  def ==(other)
    other.instance_of?(self.class) && @name == other.name
  end
  alias_method :eql?, :==
  #...
end
like image 189
Vincent Paca Avatar answered Oct 21 '22 07:10

Vincent Paca