Equal? ist nicht eql?

Ähnlich ist nicht gleich

In Rubyland gibt es mehrere Möglichkeiten, Objekte miteinander zu vergleichen. Object bietet dafür typischerweise == und eql?.
Zwei Strings werden miteinander verglichen:

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

Obwohl die beiden Strings Ruby und RUBY sich sehr ähnlich sind, sind sie doch nicht gleich, da der Stringvergleich Case sensitiv ist. Die Methode eql? ist dabei lediglich ein Alias für ==.

Gleich ist nicht das Selbe

Die folgenden Strings sind offensichtlich auf den ersten Blick gleich:

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

Auch wenn alle Strings formal gleich sind und den gleichen Wert “Ruby” repräsentieren, heißt das nicht, das es sich um die selben Objekte handelt:

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

Zwar sehen sich eql? und equal? sehr ähnlich, aber sie unterscheiden sich in einem entscheidenen Punkt:

  • eql? prüft (abhängig von der Klasse), ob es sich um Objekte handelt, die den gleichen Wert repräsentieren
  • equal? stellt fest, anhand der Objekt ID, ob es sich um die selben Objekte handelt

Jedes Objekt hat eine eindeutige Objekt ID:

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

Ähnlich kann gleich sein

Da Gleichheit abhängig von der Klasse ist, ist sie in verschiedenen Klassen auch unterschiedlich implementiert. Deshalb ist es durchaus üblich, eql? zu überschreiben.
Der folgende Monkey Patch dient lediglich zu Veranschaulichungszwecken und soll in keinem Fall zum Nachahmen animieren:

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

Ähnliche Strings sind dann auch unabhängig von Groß/ Kleinschreibung gleich:

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

Allerdings sollte equal? niemals überschrieben werden.