next up previous contents index
Search Next: Kontrollstrukturen und Wertebereiche Up: Operatoren Previous: Anordnung   Contents   Index


Gleichheit

Ruby scheint auf den ersten Blick viele Möglichkeiten zu besitzen, um zwei Objekte auf "`Gleichheit"' zu überprüfen. Der Grund ist, dass es auch viele Möglichkeiten gibt, die "`Gleichheit"' von Objekten zu definieren.

== kontrolliert, ob die beteiligten Objekte den gleichen Wert haben. eql? überprüft zusätzlich die Klassen der Objekte, deswegen sind 1 und 1.0 nicht "`gleich"'. Die dritte Methode equal? geht einen komplett anderen Weg, indem sie die internen Objektnummern der beteiligten Objekte vergleicht.

1 == 1                  #-> true
1.eql?(1)               #-> true
1.equal?(1)             #-> true

1+1 == 1+1              #-> true
(1+1).eql?(1+1)         #-> true
(1+1).equal?(1+1)       #-> true

Fixnum-Objekte werden besonders behandelt, da eine mehrfache Nennung keine unterschiedlichen Objekte erzeugt. Aus Gründen der Effizienz haben Fixnums überhaupt keine Objektnummern bzw. sind ihre eigene, so dass der gleiche Wert für Objektidentität ausreicht.

2**31 == 2**31          #-> true
(2**31).eql?(2**31)     #-> true
(2**31).equal?(2**31)   #-> false

1.0 == 1.0              #-> true
1.0.eql?(1.0)           #-> true
1.0.equal?(1.0)         #-> false

"ab" == "ab"            #-> true
"ab".eql?("ab")         #-> true
"ab".equal?("ab")       #-> false

Bignum-, Float und String-Literale sind "`normale"' Objekte, die eigene Objektnummern besitzen und bei jeder Nennung neu erzeugt werden.


\epsfig{height=36pt,file=images/chan.eps}Diese Eigenschaft spielt dann eine Rolle, wenn man ein Ruby-Skript optimieren möchte: Die Entfernung von Bignum-, Float- oder String-Literalen aus oft benutzten inneren Schleifen macht eine Methode schneller. \epsfig{height=10pt,file=images/ruby.eps}

1 == 1.0                #-> true
1.eql?(1.0)             #-> false
1.equal?(1.0)           #-> false

Hier ist das zweite Resultat false, weil ein Fixnum mit einem Float verglichen wird.

In der Gruppe der Vergleichsoperatoren muss nur noch === näher erläutert werden. Dieser Vergleich wird meistens in case-Anweisungen eingesetzt, um den Schaltwert mit den Vergleichskriterien zu überprüfen:

case (number = rand(10).to_s)
  when /[2357]$/ then p "prim"
  when "0", "1" then p "0 oder 1"
  else p "zusammengesetzt"
end

# ist gleichwertig mit
number = rand(10).to_s
if /[2357]$/ === number then p "prim"
elsif "0" === number or "1" === number
  p "0 oder 1"
else p "zusammengesetzt"
end

Nun bedeutet === für reguläre Ausdrücke das Gleiche wie =~, bei Strings ist es äquivalent zu ==, so dass Ruby eigentlich folgende Anweisungen ausführt:

number = rand(10).to_s
if /[2357]$/ =~ number then p "prim"
elsif "0" == number or "1" == number
  p "0 oder 1"
else p "zusammengesetzt"
end


\epsfig{height=36pt,file=images/chan.eps}Eine sinnvolle Definition von === ermöglicht den Einsatz eigener Objekte in den when-Bedingungen einer case-Anweisung. \epsfig{height=10pt,file=images/ruby.eps}


next up previous contents index
Search Next: Kontrollstrukturen und Wertebereiche Up: Operatoren Previous: Anordnung   Contents   Index
(C) 2002 by dpunkt.de, Armin Roehrl, Stefan Schmiedl, Clemens Wyss 2002-01-20