Equal? is not eql?

Similar is not equal

In Rubyland there are various alternative to compare objects with each other. That is what Object provides == and eql? for typically.
Two Strings are compared with each other:

'Ruby' == 'RUBY' # => false
'Ruby'.eql? 'RUBY' # => false

Though both Strings Ruby and RUBY are quite similar, they are not the equal, because String comparisons are case sensitive. The method Eql? is simply an alias for ==.

Equal does not mean the same

The subsequent Strings are obviously equal:

'Ruby' == 'Ruby' # => true
'Ruby'.eql? 'Ruby' # => true

All above Strings formally are equal and represent the same value Ruby. But that does not mean, that they are the same objects:

'Ruby'.equal? 'Ruby' # => false

Indeed eql? and equal? look quite similar, but they differ in a crucial point:

  • eql? verifies (depending on the class), if the objects represent the same value
  • equal? asserts, if the objects are the very same based on the object ID

Each object has its own unique object ID:

'Ruby'.object_id # => 42489320
'Ruby'.object_id # => 42483060
'Ruby'.object_id # => 42476400

Similar can be equal

Since equality depends on the class, its implementation varies from class to class. That is intended. That is why, it is common to overwrite eql?.
The following monkey patch only is for demonstration reasons and is not intended to encourage imitation:

class String
  def eql? comparison_string
    self.downcase == comparison_string.to_s.downcase
  end
end

Similar Strings are equal even case insensitive, from now on:

'Ruby'.eql? 'RUBY' # => true

However equal? should never be overwritten.