Er kann 3 verschiedene Bedeutungen haben:
'<<' als gewöhnliche Methode
In den meisten Fällen ist '<<' eine Methode, die wie die anderen definiert ist, in Ihrem Fall bedeutet es "an das Ende dieses Arrays anhängen" (siehe auch aquí ).
Das ist Ihr spezieller Fall, aber es gibt auch viele andere Gelegenheiten, bei denen Sie auf die Methode "<<" stoßen werden. Ich werde sie nicht als "Operator" bezeichnen, da es sich in Wirklichkeit um eine Methode handelt, die für ein Objekt definiert ist, das von Ihnen überschrieben oder für Ihre eigenen Objekte implementiert werden kann. Andere Fälle von "<<
- String-Verkettung: "a" << "b"
- Schreiben der Ausgabe in ein IO: io << "Eine Textzeile \n "
- Schreiben von Daten in einen Message Digest, HMAC oder Cipher: sha << "Zu hashender Text"
- Linksverschiebung einer OpenSSL::BN: bn << 2
- ...
Definition der Singleton-Klasse
Dann gibt es noch die mysteriöse Verschiebung des aktuellen Geltungsbereichs (= Wechsel des Selbst) innerhalb des Programmablaufs:
class A
class << self
puts self # self is the singleton class of A
end
end
a = A.new
class << a
puts self # now it's the singleton class of object a
end
Das Geheimnis class << self
hat mich dazu veranlasst, mich mit den Interna zu befassen. Während in allen von mir erwähnten Beispielen <<
ist eigentlich eine Methode, die in einer Klasse definiert ist, d.h.
obj << stuff
ist gleichbedeutend mit
obj.<<(stuff)
die class << self
(oder jedes andere Objekt anstelle des Selbst) ist wirklich anders. Es ist wirklich eine eingebaute Funktion der Sprache selbst, in CRuby ist es definiert in zerlegen.y als
k_class tLSHFT expr
k_class
ist das Schlüsselwort "class", wobei tLSHFT
ist ein '<<'-Zeichen und expr
ist ein beliebiger Ausdruck. Das heißt, Sie können tatsächlich schreiben
class << <any expression>
und erhalten verlagert in die Singleton-Klasse des Ergebnisses des Ausdrucks. Die tLSHFT
Sequenz wird als 'NODE_SCLASS'-Ausdruck geparst, der als Definition der Singleton-Klasse (vgl. node.c)
case NODE_SCLASS:
ANN("singleton class definition");
ANN("format: class << [nd_recv]; [nd_body]; end");
ANN("example: class << obj; ..; end");
F_NODE(nd_recv, "receiver");
LAST_NODE;
F_NODE(nd_body, "singleton class definition");
break;
Hier Dokumente
Hier Dokumente verwenden '<<' auf eine Weise, die wiederum völlig anders ist. Sie können eine Zeichenkette, die sich über mehrere Zeilen erstreckt, bequem durch die Deklaration
here_doc = <<_EOS_
The quick brown fox jumps over the lazy dog.
...
_EOS_
Um den "here doc operator" zu unterscheiden, muss ein beliebiges String-Begrenzungszeichen unmittelbar auf das "<<" folgen. Alles, was zwischen diesem ersten Begrenzungszeichen und dem zweiten Vorkommen desselben Begrenzungszeichens liegt, wird Teil der endgültigen Zeichenkette sein. Es ist auch möglich, '<<-' zu verwenden, mit dem Unterschied, dass bei der Verwendung des letzteren jedes führende oder nachfolgende Leerzeichen ignoriert wird.