Gleichheitsoperatoren: == und! =
Der Operator ==, auch als Gleichheit oder Doppelgleichheit bezeichnet, gibt true zurück, wenn beide Objekte gleich sind, und false, wenn dies nicht der Fall ist.
"koan" == "koan" # Output: => true
Der Operator! =, Auch als Ungleichung bekannt, ist das Gegenteil von ==. Es wird true zurückgegeben, wenn beide Objekte nicht gleich sind, und false, wenn sie gleich sind.
"koan" != "discursive thought" # Output: => true
Beachten Sie, dass zwei Arrays mit denselben Elementen in einer anderen Reihenfolge nicht gleich sind, Groß- und Kleinbuchstaben desselben Buchstabens nicht gleich sind und so weiter.
Wenn beim Vergleichen von Zahlen verschiedener Typen (z. B. Integer und Float) der numerische Wert gleich ist, gibt == true zurück.
2 == 2.0 # Output: => true
gleich?
Im Gegensatz zum Operator ==, der prüft, ob beide Operanden gleich sind, prüft die Methode same, ob sich die beiden Operanden auf dasselbe Objekt beziehen. Dies ist die strengste Form der Gleichheit in Ruby.
Beispiel: a = "Zen" b = "Zen"
a.object_id # Output: => 20139460
b.object_id # Output :=> 19972120
a.equal? b # Output: => false
Im obigen Beispiel haben wir zwei Zeichenfolgen mit demselben Wert. Es handelt sich jedoch um zwei unterschiedliche Objekte mit unterschiedlichen Objekt-IDs. Daher ist das gleiche? Methode gibt false zurück.
Versuchen wir es noch einmal, nur dieses Mal wird b ein Verweis auf a sein. Beachten Sie, dass die Objekt-ID für beide Variablen gleich ist, da sie auf dasselbe Objekt verweisen.
a = "zen"
b = a
a.object_id # Output: => 18637360
b.object_id # Output: => 18637360
a.equal? b # Output: => true
Äql?
In der Hash-Klasse ist die Gl. Methode wird verwendet, um Schlüssel auf Gleichheit zu testen. Einige Hintergrundinformationen sind erforderlich, um dies zu erklären. Im allgemeinen Kontext des Rechnens nimmt eine Hash-Funktion eine Zeichenfolge (oder eine Datei) beliebiger Größe und generiert eine Zeichenfolge oder Ganzzahl fester Größe, die als Hashcode bezeichnet wird und üblicherweise nur als Hash bezeichnet wird. Einige häufig verwendete Hashcode-Typen sind MD5, SHA-1 und CRC. Sie werden in Verschlüsselungsalgorithmen, bei der Datenbankindizierung, bei der Überprüfung der Dateiintegrität usw. verwendet. Einige Programmiersprachen, wie z. B. Ruby, bieten einen Sammlungstyp namens Hash-Tabelle. Hash-Tabellen sind wörterbuchartige Sammlungen, die Daten paarweise speichern und aus eindeutigen Schlüsseln und ihren entsprechenden Werten bestehen. Unter der Haube werden diese Schlüssel als Hashcodes gespeichert. Hash-Tabellen werden üblicherweise nur als Hashes bezeichnet. Beachten Sie, wie sich das Wort Hash auf einen Hashcode oder eine Hash-Tabelle beziehen kann.
Ruby bietet eine integrierte Methode namens Hash zum Generieren von Hashcodes. Im folgenden Beispiel wird eine Zeichenfolge verwendet und ein Hashcode zurückgegeben. Beachten Sie, dass Zeichenfolgen mit demselben Wert immer denselben Hashcode haben, obwohl es sich um unterschiedliche Objekte handelt (mit unterschiedlichen Objekt-IDs).
"meditation".hash # Output: => 1396080688894079547
"meditation".hash # Output: => 1396080688894079547
"meditation".hash # Output: => 1396080688894079547
Die Hash-Methode ist im Kernel-Modul implementiert, das in der Object-Klasse enthalten ist. Dies ist das Standardstammverzeichnis aller Ruby-Objekte. Einige Klassen wie Symbol und Integer verwenden die Standardimplementierung, andere wie String und Hash stellen ihre eigenen Implementierungen bereit.
Symbol.instance_method(:hash).owner # Output: => Kernel
Integer.instance_method(:hash).owner # Output: => Kernel
String.instance_method(:hash).owner # Output: => String
Hash.instance_method(:hash).owner # Output: => Hash
Wenn wir in Ruby etwas in einem Hash (einer Sammlung) speichern, wird das als Schlüssel bereitgestellte Objekt (z. B. Zeichenfolge oder Symbol) in einen Hashcode konvertiert und als Hashcode gespeichert. Wenn wir später ein Element aus dem Hash (Sammlung) abrufen, stellen wir ein Objekt als Schlüssel bereit, das in einen Hashcode konvertiert und mit den vorhandenen Schlüsseln verglichen wird. Wenn eine Übereinstimmung vorliegt, wird der Wert des entsprechenden Elements zurückgegeben. Der Vergleich erfolgt mit der Gleichung? Methode unter der Haube.
"zen".eql? "zen" # Output: => true
# is the same as
"zen".hash == "zen".hash # Output: => true
In den meisten Fällen ist die Gl. Methode verhält sich ähnlich wie die == Methode. Es gibt jedoch einige Ausnahmen. Zum Beispiel ist Gl. führt keine implizite Typkonvertierung durch, wenn eine Ganzzahl mit einem Float verglichen wird.
2 == 2.0 # Output: => true
2.eql? 2.0 # Output: => false
2.hash == 2.0.hash # Output: => false
Operator für die Fallgleichheit: ===
Viele der in Ruby integrierten Klassen, wie z. B. String, Range und Regexp, bieten ihre eigenen Implementierungen des Operators ===, auch bekannt als Groß- / Kleinschreibung, Dreifachgleichheit oder Dreifachgleichung. Da es in jeder Klasse unterschiedlich implementiert ist, verhält es sich je nach Objekttyp, für den es aufgerufen wurde, unterschiedlich. Im Allgemeinen wird true zurückgegeben, wenn das Objekt auf der rechten Seite zu dem Objekt auf der linken Seite gehört. Beispielsweise kann damit getestet werden, ob ein Objekt eine Instanz einer Klasse (oder einer ihrer Unterklassen) ist.
String === "zen" # Output: => true
Range === (1..2) # Output: => true
Array === [1,2,3] # Output: => true
Integer === 2 # Output: => true
Das gleiche Ergebnis kann mit anderen Methoden erzielt werden, die wahrscheinlich am besten für den Job geeignet sind. Normalerweise ist es besser, Code zu schreiben, der leicht zu lesen ist, indem er so explizit wie möglich ist, ohne die Effizienz und Prägnanz zu beeinträchtigen.
2.is_a? Integer # Output: => true
2.kind_of? Integer # Output: => true
2.instance_of? Integer # Output: => false
Beachten Sie, dass das letzte Beispiel false zurückgegeben hat, da Ganzzahlen wie 2 Instanzen der Fixnum-Klasse sind, die eine Unterklasse der Integer-Klasse ist. Das ===, is_a? und instance_of? Methoden geben true zurück, wenn das Objekt eine Instanz der angegebenen Klasse oder einer Unterklasse ist. Die Methode instance_of ist strenger und gibt nur dann true zurück, wenn das Objekt eine Instanz dieser exakten Klasse und keine Unterklasse ist.
Das is_a? und kind_of? Methoden werden im Kernel-Modul implementiert, das von der Object-Klasse gemischt wird. Beide sind Aliase nach derselben Methode. Lassen Sie uns überprüfen:
Kernel.instance_method (: kind_of?) == Kernel.instance_method (: is_a?) # Ausgabe: => true
Bereichsimplementierung von ===
Wenn der Operator === für ein Bereichsobjekt aufgerufen wird, gibt er true zurück, wenn der Wert rechts in den Bereich links fällt.
(1..4) === 3 # Output: => true
(1..4) === 2.345 # Output: => true
(1..4) === 6 # Output: => false
("a".."d") === "c" # Output: => true
("a".."d") === "e" # Output: => false
Denken Sie daran, dass der Operator === die Methode === des linken Objekts aufruft. Also (1..4) === 3 ist äquivalent zu (1..4). === 3. Mit anderen Worten, die Klasse des linken Operanden definiert, welche Implementierung der === Methode sein wird aufgerufen, daher sind die Operandenpositionen nicht austauschbar.
Regexp Implementierung von ===
Gibt true zurück, wenn die Zeichenfolge rechts mit dem regulären Ausdruck links übereinstimmt. / zen / === "Zazen heute üben" # Ausgabe: => true # ist dasselbe wie "Zazen heute üben" = ~ / zen /
Implizite Verwendung des Operators === für case / when-Anweisungen
Dieser Operator wird auch unter der Haube für case / when-Anweisungen verwendet. Das ist die häufigste Verwendung.
minutes = 15
case minutes
when 10..20
puts "match"
else
puts "no match"
end
# Output: match
Wenn Ruby im obigen Beispiel implizit den doppelten Gleichheitsoperator (==) verwendet hätte, würde der Bereich 10..20 nicht als gleich einer Ganzzahl wie 15 angesehen. Sie stimmen überein, weil der dreifach gleiche Operator (===) ist implizit in allen case / when-Anweisungen verwendet. Der Code im obigen Beispiel entspricht:
if (10..20) === minutes
puts "match"
else
puts "no match"
end
Mustervergleichsoperatoren: = ~ und! ~
Die Operatoren = ~ (Equal-Tilde) und! ~ (Bang-Tilde) werden verwendet, um Zeichenfolgen und Symbole mit Regex-Mustern abzugleichen.
Die Implementierung der Methode = ~ in den Klassen String und Symbol erwartet einen regulären Ausdruck (eine Instanz der Regexp-Klasse) als Argument.
"practice zazen" =~ /zen/ # Output: => 11
"practice zazen" =~ /discursive thought/ # Output: => nil
:zazen =~ /zen/ # Output: => 2
:zazen =~ /discursive thought/ # Output: => nil
Die Implementierung in der Regexp-Klasse erwartet eine Zeichenfolge oder ein Symbol als Argument.
/zen/ =~ "practice zazen" # Output: => 11
/zen/ =~ "discursive thought" # Output: => nil
Wenn in allen Implementierungen die Zeichenfolge oder das Symbol mit dem Regexp-Muster übereinstimmt, wird eine Ganzzahl zurückgegeben, die die Position (den Index) der Übereinstimmung darstellt. Wenn keine Übereinstimmung vorliegt, wird null zurückgegeben. Denken Sie daran, dass in Ruby jeder ganzzahlige Wert "wahr" und null "falsch" ist, sodass der Operator = ~ in if-Anweisungen und ternären Operatoren verwendet werden kann.
puts "yes" if "zazen" =~ /zen/ # Output: => yes
"zazen" =~ /zen/?"yes":"no" # Output: => yes
Mustervergleichsoperatoren sind auch nützlich, um kürzere if-Anweisungen zu schreiben. Beispiel:
if meditation_type == "zazen" || meditation_type == "shikantaza" || meditation_type == "kinhin"
true
end
Can be rewritten as:
if meditation_type =~ /^(zazen|shikantaza|kinhin)$/
true
end
Der Operator! ~ Ist das Gegenteil von = ~. Er gibt true zurück, wenn keine Übereinstimmung vorliegt, und false, wenn eine Übereinstimmung vorliegt.
Weitere Informationen finden Sie in diesem Blogbeitrag .
"a" == "a"
,"a" === "a"
und"a".eql? "a"
. Aber das ist falsch:"a".equal? "a"
(Meins ist Rubin 1.9.2-p180)