'<<' als gewöhnliche Methode
In den meisten Fällen ist '<<' eine Methode, die wie die anderen definiert ist. In Ihrem Fall bedeutet dies "am Ende dieses Arrays hinzufügen" (siehe auch hier ).
Das ist in Ihrem speziellen Fall so, aber es gibt auch viele andere Fälle, in denen Sie auf die Methode "<<" stoßen. Ich werde es nicht "Operator" nennen, da es wirklich eine Methode ist, 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"
- Ausgabe in ein E / A schreiben: io << "Eine Textzeile \ n"
- Schreiben von Daten in einen Message Digest, HMAC oder Chiffre: sha << "Zu hashender Text"
- Linksverschiebung eines OpenSSL :: BN: bn << 2
- ...
Singleton-Klassendefinition
Dann gibt es die mysteriöse Verschiebung des aktuellen Umfangs (= Veränderung des Selbst) innerhalb des Programmflusses:
class A
class << self
puts self
end
end
a = A.new
class << a
puts self
end
Das Rätsel class << self
ließ mich über die Einbauten dort nachdenken. Während in allen Beispielen, die ich erwähnte, <<
wirklich eine Methode ist, die in einer Klasse definiert ist, dh
obj << stuff
ist äquivalent zu
obj.<<(stuff)
Das class << self
Konstrukt (oder irgendein Objekt anstelle des Selbst) ist wirklich anders. Es ist wirklich ein eingebautes Merkmal der Sprache selbst, in CRuby ist es in parse.y als definiert
k_class tLSHFT expr
Dabei ist tLSHFT ein '<<' Token, k_class das Schlüsselwort 'class' und expr ein beliebiger Ausdruck. Das heißt, Sie können tatsächlich schreiben
class << <any expression>
und wird in die Singleton-Klasse des Ergebnisses des Ausdrucks 'verschoben'. Die tLSHFT-Sequenz wird als 'NODE_SCLASS'-Ausdruck analysiert, der als Singleton- Klassendefinition bezeichnet wird (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
Und wie könnte ich diese vergessen? Hier verwenden Dokumente '<<' auf eine Weise, die wiederum völlig anders ist. Sie können eine Zeichenfolge definieren, die sich bequem über mehrere Zeilen erstreckt, indem Sie deklarieren
here_doc = <<_EOS_
The quick brown fox jumps over the lazy dog.
...
_EOS_
Um den 'here doc operator' zu unterscheiden, muss ein beliebiges String-Trennzeichen unmittelbar auf das '<<' folgen. Alles zwischen diesem anfänglichen Trennzeichen und dem zweiten Auftreten desselben Trennzeichens ist Teil der endgültigen Zeichenfolge. Es ist auch möglich, '<< -' zu verwenden. Der Unterschied besteht darin, dass bei Verwendung des letzteren führende oder nachfolgende Leerzeichen ignoriert werden.