/ / Grundlegendes zu Array.map (&: method) `[duplicate] - Ruby, Symbol

Grundlegendes zu Array.map (&: method) `[duplicate] - Ruby, Symbol

Warum tut:

[1,2,3,4,5].map(&:to_s) #=> ["1", "2", "3", "4", "5"]

Arbeit aber:

[1,2,3,4,5].map(&:*(2))

wirft einen unerwarteten Syntaxfehler?

Antworten:

3 für die Antwort № 1

& heißt das to_proc Operator. Es nennt das to_proc method für den Ausdruck, der darauf folgt, und übergibt den resultierenden Proc als Block an die Methode.

Im Falle des &:to_s, :to_s Ist ein Symbol, also ruft der Operator an Symbol#to_proc. Die Dokumente sind etwas unübersichtlich, aber es genügt zu sagen, dass diese beiden Ausdrücke mehr oder weniger gleichwertig sind:

my_proc = :to_s.to_proc
my_proc = Proc.new {|obj| obj.to_s }

Also die Antwort auf die Frage "Warum nicht?" &:*(2) Arbeit? "ist das der Ausdruck, der dem folgt & Operator, :*(2)ist kein gültiger Ruby-Ausdruck. Es macht für den Ruby-Parser ungefähr so ​​viel Sinn wie "hello"(2).

Es gibt übrigens eine Möglichkeit, das zu tun, was Sie versuchen:

[1,2,3,4,5].map(&2.method(:*))
# => [2, 4, 6, 8, 10]

In dem obigen Code 2.method(:*) gibt einen Verweis auf die zurück * Methode des Objekts 2 Als ein Methode Objekt. Methodenobjekte verhalten sich ähnlich wie Proc-Objekte und reagieren darauf to_proc. Das obige ist jedoch nicht genau gleichwertig 2 * n eher, als n * 2 (eine Unterscheidung, die keine Rolle spielt, wenn n ist auch eine Zahl) - und es ist nicht knapper oder lesbarer als {|n| n * 2 }und so selten die Mühe wert.


-1 für die Antwort № 2

Kaufmännisches Und-Objekt (&: Methode)

Der Operator & kann auch verwendet werden, um ein Objekt als Block an eine Methode zu übergeben, wie im folgenden Beispiel:

arr = [ 1, 2, 3, 4, 5 ]

arr.map { |n| n.to_s }
arr.map &:to_s

Beide obigen Beispiele haben das gleiche Ergebnis. In beiden Fällen nimmt die Map-Methode das Arr-Array und einen Block an und führt dann den Block für jedes Element des Arrays aus. Der Code im Block wird für jedes Element to_s ausgeführt und von Ganzzahlen in Strings konvertiert. Die Map-Methode gibt dann ein neues Array zurück, das die konvertierten Elemente enthält.

Das erste Beispiel ist weit verbreitet und wird häufig verwendet. Das zweite Beispiel mag auf den ersten Blick etwas kryptisch aussehen. Lass "sehen was passiert":

In Ruby, Elemente, denen der Doppelpunkt vorangestellt ist (:) sind Symbole. Wenn Sie mit der Symbol-Klasse / dem Datentyp nicht vertraut sind, schlage ich vor, dass Sie sie bei Google einlesen und einige Artikel lesen, bevor Sie fortfahren. Alle Methodennamen in Ruby werden intern als Symbole gespeichert. Indem wir einem Methodennamen einen Doppelpunkt voranstellen, konvertieren wir die Methode nicht in ein Symbol. Auch rufen wir die Methode nicht auf. Wir übergeben lediglich den Namen der Methode (Referenzierung der Methode). Im obigen Beispiel übergeben wir: to_s, eine Referenz auf die to_s-Methode, an das kaufmännische Und (&) - Operator, das eine proc (durch Aufrufen von to_proc unter der Haube) erstellt. Die proc nimmt einen Wert als Argument an, ruft to_s auf und gibt den in einen String konvertierten Wert zurück.

Obwohl die :Das to_s-Symbol ist immer dasselbe. Beim Ausführen der Map-Schleife wird auf die to_s-Methode der Klasse verwiesen, die jedem Array-Element entspricht. Wenn wir der map-Methode ein Array wie [21, 4.453,: foobar,] übergeben, wird die to_s-Methode der Fixnum-Klasse auf das erste Element angewendet (aufgerufen), und die to_s-Methode der Float-Klasse wird angewendet Das zweite Element und die to_s-Methode der Symbol-Klasse werden auf das dritte Element angewendet. Dies ist sinnvoll, da wir nicht die tatsächliche to_s-Methode an den kaufmännischen Und-Operator übergeben, sondern nur ihren Namen.

Im Folgenden finden Sie ein Beispiel zum Erstellen einer proc, die ein Argument verwendet, eine Methode aufruft und das Ergebnis der Methode zurückgibt.

p = :upcase.to_proc
p.call("foo bar")
Output:
=> "FOO BAR"

Lassen Sie uns in arr.map &: to_s nachsehen, was los ist

  1. Bei jeder Map-Iteration wird ein Element des Arrays (eine Ganzzahl) an &: to_s übergeben
  2. Das :Das to_s-Symbol (das eine Referenz auf die to_s-Methode ist) wird an den Operator & übergeben, der eine Prozedur erstellt, die ein Argument (ein Array-Element) akzeptiert, to_s für das Argument aufruft und den in String konvertierten Wert zurückgibt.
  3. Die Map-Methode gibt ein neues Array zurück, das die Zeichenfolgen "1", "2", "3", "4" und "5" enthält.