Was bedeutet << in Ruby?

79

Ich habe Code:

  def make_all_thumbs(source)
    sizes = ['1000','1100','1200','800','600']
    threads = []
    sizes.each do |s|
      threads << Thread.new(s) {
        create_thumbnail(source+'.png', source+'-'+s+'.png', s)
      }
    end
  end

was tut <<bedeuten?

Vyacheslav Loginov
quelle

Antworten:

140

'<<' 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 # 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 Rätsel class << selfließ 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 << selfKonstrukt (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.

prägen
quelle
4
Sehr gründliche Antwort. Könnte Anfänger verwirren, aber wie ein weiser Mann (vielleicht) gesagt hat: "Stellen Sie eine breite Frage, erhalten Sie eine gründliche Antwort".
Kelvin
1
Hallo, danke @emboss: << entspricht also dem Aufruf der Push-Methode für ein Array?
BKSpurgeon
30

Wird meistens in Arrays verwendet, um den Wert an das Ende des Arrays anzuhängen.

a = ["orange"]
a << "apple"
puts a

gibt dies

  ["Orange", "Apfel"] 
Ergebnis.

Shajin
quelle
3
Eine weitere Verwendung <<ist in der Klassenvererbung
Zabba
7

Mit diesem Operator können Sie vorhandene Arrays durch Anhängen neuer Elemente füttern .

Im obigen Beispiel füllen Sie das leere Array nur threadsmit 5 neuen Threads.

Emiliano Poggi
quelle
6

'a << b' bedeutet, b an das Ende von a anzuhängen

Aditya Mukherji
quelle
6

In Ruby haben Sie immer mehr die eine Möglichkeit, Dinge zu tun. Ruby hat also einige nette Verknüpfungen für gebräuchliche Methodennamen. Wie dieses ist für .push, anstatt den Namen der .push-Methode einzugeben, können Sie einfach <<, den Verkettungsoperator, verwenden. In einigen Fällen können Sie diese für denselben Vorgang verwenden .push und + mit <<.

Wie Sie in diesem Beispiel sehen können:

alphabet = ["a", "b", "c"]
alphabet << "d" # Update me!
alphabet.push("e") # Update me!
print alphabet 
caption = "the boy is surrounded by "
caption << "weezards!" # Me, too!
caption += " and more. " # Me, too!
# .push can no be uses for concatenate 
print caption

Sie sehen also, dass das Ergebnis ist:

["a", "b", "c", "d", "e"]
the boy is surrounded by weezards! and more.

Mit dem Operator << können Sie ein Element in ein Array verschieben oder eine Zeichenfolge mit einem anderen verknüpfen.

Dies bedeutet also, dass ein neuer Element- / Objekt-Thread-Typ erstellt und in das Array verschoben wird.

 threads << Thread.new(s) {
        create_thumbnail(source+'.png', source+'-'+s+'.png', s)
      }
Jesus Gonzalez
quelle
5

In Ruby wird der Operator '<<' grundsätzlich verwendet für:

  1. Anhängen eines Werts im Array (an der letzten Position)

    [2, 4, 6] << 8 Es wird [2, 4, 6, 8] geben.

  2. Es wird auch für einige aktive Aufzeichnungsvorgänge in Ruby verwendet. Zum Beispiel haben wir ein Cart- und LineItem-Modell, das als cart has_many line_items verknüpft ist. Cart.find (A) .line_items gibt das ActiveRecord :: Associations-Objekt mit Werbebuchungen zurück, die zum Warenkorb 'A' gehören.

Um nun ein weiteres line_item (X) zum Warenkorb (A) hinzuzufügen (oder zu verknüpfen),

Cart.find(A).line_items << LineItem.find(X)
  1. Fügen Sie nun ein weiteres LineItem zum selben Warenkorb 'A' hinzu, aber dieses Mal werden wir kein line_item-Objekt erstellen (ich meine, es wird kein Activerecord-Objekt manuell erstellt).

    Cart.find (A) .line_items << LineItem.new

Im obigen Code speichert << das Objekt und hängt es an das aktive Datensatzzuordnungsarray auf der linken Seite an.

Und viele andere, die bereits in den obigen Antworten behandelt wurden.

Shubham Mishra
quelle
Nicht jeder kennt dieses Verhalten von <<. Danke, dass du es erwähnt hast.
Ammar Shah
0

Es bedeutet, am Ende hinzufügen (anhängen).

a = [1,2,3]
a << 4
a = [1,2,3,4]
VeronikaS
quelle
0

Seit Ruby 2.6 ist die <<Methode auch auf definiertProc .

Mit Proc # << können zwei oder mehr Procs erstellt werden.

maicher
quelle