Was ist in Ruby der Unterschied zwischen == und ===? Das RDoc sagt
Fallgleichheit - Für die Klasse Object entspricht dies praktisch dem Aufruf von # ==, wird jedoch normalerweise von Nachkommen überschrieben, um eine aussagekräftige Semantik in case-Anweisungen bereitzustellen.
Ist #==
das gleiche wie ==
? Und könnten Sie ein Beispiel dafür geben, wann / wie dies in case-Anweisungen verwendet wird?
Antworten:
Die beiden haben wirklich nichts miteinander zu tun. Insbesondere
#==
ist der Gleichheitsoperator und#===
hat absolut nichts mit Gleichheit zu tun. Ich persönlich finde es sehr schade , dass#===
sieht so ähnlich ,#==
verwendet das Gleichheitszeichen und oft wird die gerufene Fall Gleichheitsoperator , triple equals Operator oder threequals Operator , wenn es wirklich nichts mit Gleichheit zu tun hat.Ich rufe
#===
den Fall-Subsumtions-Operator an (es ist das Beste, was ich mir vorstellen kann, ich bin offen für Vorschläge, insbesondere von englischen Muttersprachlern).Die beste Art zu beschreiben
a === b
ist: "Wenn ich eine Schublade beschriftet habea
, ist es sinnvoll, sieb
einzulegen?"So wird zum Beispiel
Module#===
getestet, obb.is_a?(a)
. Wenn jaInteger === 2
, ist es sinnvoll,2
eine Box mit der Aufschrift zu verwendenInteger
? Ja tut es. Was ist mitInteger === 'hello'
? Offensichtlich nicht.Ein anderes Beispiel ist
Regexp#===
. Es testet auf ein Match. Ist es sinnvoll,'hello'
eine beschriftete Box einzulegen/el+/
? Ja tut es.Für Sammlungen wie Bereiche
Range#===
wird dies als Mitgliedschaftstest definiert: Es ist sinnvoll, ein Element in ein Feld mit einer Sammlung einzufügen, wenn sich dieses Element in der Sammlung befindet.Das ist es also, was es
#===
tut: Es testet, ob das Argument unter dem Empfänger zusammengefasst werden kann.Was hat das mit
case
Ausdrücken zu tun? Einfach:case foo when bar baz end
ist das gleiche wie
if bar === foo baz end
quelle
Array#===
ist nicht als Mitgliedschaft in Ruby 1.8 oder 1.9.1 definiert.Range#===
ist aber.Ja, mit
#==
den Dokumenten ist "die Instanzmethode==
des aktuellen Objekts" gemeint .===
wird in case-Anweisungen als solche verwendet:case obj when x foo when y bar end
Ist das gleiche wie
if x === obj foo elsif y === obj bar end
Einige Klassen, die ihre eigenen definieren,
===
sind Range (um sich so zu verhalteninclude?
), Class (um sich so zu verhaltenobj.is_a?(klass)
) undRegexp
(um sich so zu verhalten,=~
außer dass ein Boolescher Wert zurückgegeben wird). Einige Klassen, die keine eigenen definieren,===
sind die numerischen Klassen und String.Damit
case x when 0 puts "Lots" when Numeric puts(100.0 / x) when /^\d+$/ puts(100.0 / x.to_f) default raise ArgumentError, "x is not a number or numeric string" end
ist das gleiche wie
if 0 == x puts "Lots" elsif x.is_a? Numeric puts(100.0 / x) elsif x =~ /^\d+$/ puts(100.0 / x.to_f) else raise ArgumentError, "x is not a number or numeric string" end
quelle
case x; when string --> if "string" == x
?case x; when string
ist äquivalent zuif string === x
, was, wenn esstring
eine Zeichenfolge enthält, äquivalent zu istif string == x
. Ebensocase x; when "string"
ist äquivalent zuif "string" === x
undif "string" == x
.Unterhaltsame Tatsache,
===
wird auch verwendet, um Ausnahmen in abzugleichenrescue
Hier ist ein Beispiel
class Example def self.===(exception) puts "Triple equals has been called." true end end raise rescue Example # => prints "Triple equals has been called." # => no exception raised
Dies wird verwendet, um Systemfehler abzugleichen.
SystemCallError.===
wurde so definiert, dass sie true zurückgibt, wenn beide dieselbe errno haben. Mit diesem System können Aufruffehler mit derselben Fehlernummer wieErrno::EAGAIN
undErrno::EWOULDBLOCK
behoben werden, indem nur einer von ihnen aufgelistet wird.quelle