Ich habe diesen Code in einem RailsCast gefunden :
def tag_names
@tag_names || tags.map(&:name).join(' ')
end
Was bedeutet das (&:name)
in map(&:name)
?
ruby
syntax
operators
parameter-passing
Collimarco
quelle
quelle
Antworten:
Es ist eine Abkürzung für
tags.map(&:name.to_proc).join(' ')
Wenn
foo
es sich um ein Objekt mit einerto_proc
Methode handelt, können Sie es an eine Methode als übergeben&foo
, die diese aufruftfoo.to_proc
und als Block der Methode verwendet.Die
Symbol#to_proc
Methode wurde ursprünglich von ActiveSupport hinzugefügt, wurde jedoch in Ruby 1.8.7 integriert. Dies ist seine Umsetzung:quelle
&
, dhtags.map(&:name.to_proc).join(' ')
Eine andere coole Abkürzung, die vielen unbekannt ist, ist
Das ist eine Abkürzung für
Durch Aufrufen haben
method(:foo)
wir einMethod
Objekt genommenself
, das seinefoo
Methode darstellt, und das verwendet,&
um anzuzeigen, dass es eineto_proc
Methode hat , die es in eine konvertiertProc
.Dies ist sehr nützlich, wenn Sie einen punktfreien Stil ausführen möchten . Ein Beispiel ist die Überprüfung, ob ein Array eine Zeichenfolge enthält, die der Zeichenfolge entspricht
"foo"
. Es gibt den herkömmlichen Weg:Und da ist der punktfreie Weg:
Der bevorzugte Weg sollte der am besten lesbare sein.
quelle
array.each{|e| foo(e)}
ist noch kürzer :-) +1 sowieso&method
?[1,2,3].map(&Array.method(:new))
Es ist gleichbedeutend mit
quelle
Beachten wir auch, dass kaufmännisches Und-Zeichen-
#to_proc
Magie mit jeder Klasse funktionieren kann, nicht nur mit Symbol. Viele Rubyisten definieren die#to_proc
Array-Klasse wie folgt :Das kaufmännische Und
&
sendet eineto_proc
Nachricht an seinen Operanden, der im obigen Code zur Array-Klasse gehört. Und da ich die#to_proc
Methode für das Array definiert habe , wird die Zeile wie folgt:quelle
Es ist eine Abkürzung für
tags.map { |tag| tag.name }.join(' ')
quelle
&
ruft der unäre Operatorto_proc
seinen Operanden auf. Es ist also nicht spezifisch für die Map-Methode und funktioniert tatsächlich mit jeder Methode, die einen Block nimmt und ein oder mehrere Argumente an den Block übergibt.ist das gleiche wie
&:name
verwendet nur das Symbol als den aufzurufenden Methodennamen.quelle
Josh Lees Antwort ist fast richtig, außer dass der entsprechende Ruby-Code wie folgt lauten sollte.
nicht
Wenn dieser Code
print [[1,'a'],[2,'b'],[3,'c']].map(&:first)
ausgeführt wird, teilt Ruby die erste Eingabe[1,'a']
in 1 und 'a' auf, umobj
1 zu geben, undargs*
'a', um einen Fehler zu verursachen, da das Fixnum-Objekt 1 nicht über die Methode self verfügt (dh: first).Wann
[[1,'a'],[2,'b'],[3,'c']].map(&:first)
wird ausgeführt;:first
ist ein Symbol-Objekt. Wenn&:first
also eine Map-Methode als Parameter angegeben wird, wird Symbol # to_proc aufgerufen.map sendet eine Aufrufnachricht an: first.to_proc mit Parameter
[1,'a']
, zB:first.to_proc.call([1,'a'])
wird ausgeführt.Die Prozedur to_proc in der Symbolklasse sendet eine Sende-Nachricht an ein Array-Objekt (
[1,'a']
) mit dem Parameter (: first), z[1,'a'].send(:first)
. B. wird ausgeführt.iteriert über den Rest der Elemente im
[[1,'a'],[2,'b'],[3,'c']]
Objekt.Dies ist dasselbe wie das Ausführen eines
[[1,'a'],[2,'b'],[3,'c']].map(|e| e.first)
Ausdrucks.quelle
[1,2,3,4,5,6].inject(&:+)
, dass Inject ein Lambda mit zwei Parametern (Memo und Item) erwartet und es:+.to_proc
liefert -Proc.new |obj, *args| { obj.send(self, *args) }
oder{ |m, o| m.+(o) }
Hier passieren zwei Dinge, und es ist wichtig, beide zu verstehen.
Wie in anderen Antworten beschrieben, wird die
Symbol#to_proc
Methode aufgerufen.Der Grund
to_proc
, warum das Symbol aufgerufen wird, ist, dass esmap
als Blockargument übergeben wird. Wenn Sie&
in einem Methodenaufruf vor einem Argument stehen, wird es auf diese Weise übergeben. Dies gilt für jede Ruby-Methode, nicht nurmap
für Symbole.Das
Symbol
wird in a konvertiert,Proc
weil es als Block übergeben wird. Wir können dies zeigen, indem wir versuchen, einen Proc.map
ohne kaufmännisches Und weiterzugeben :Obwohl es nicht konvertiert werden muss, weiß die Methode nicht, wie es verwendet werden soll, da sie ein Blockargument erwartet. Passen Sie es mit
&
gibt.map
den Block , es erwartet.quelle
(&: name) ist die Abkürzung für (&: name.to_proc) und entspricht
tags.map{ |t| t.name }.join(' ')
to_proc ist tatsächlich in C implementiert
quelle
map (&: name) verwendet ein aufzählbares Objekt (in Ihrem Fall Tags) und führt die Namensmethode für jedes Element / Tag aus, wobei jeder zurückgegebene Wert von der Methode ausgegeben wird.
Es ist eine Abkürzung für
Dies gibt das Array der Elementnamen (Tag-Namen) zurück
quelle
Grundsätzlich wird der Methodenaufruf
tag.name
für jedes Tag im Array ausgeführt.Es ist eine vereinfachte Rubin-Abkürzung.
quelle
Obwohl wir bereits gute Antworten haben, möchte ich aus der Perspektive eines Anfängers die zusätzlichen Informationen hinzufügen:
Dies bedeutet, dass Sie eine andere Methode als Parameter an die Kartenfunktion übergeben. (In Wirklichkeit übergeben Sie ein Symbol, das in einen Proc umgewandelt wird. Dies ist jedoch in diesem speziellen Fall nicht so wichtig.)
Wichtig ist, dass Sie einen
method
Namen habenname
, der von der Map-Methode als Argument anstelle des traditionellenblock
Stils verwendet wird.quelle
Zuerst,
&:name
ist dies eine Verknüpfung für&:name.to_proc
, bei:name.to_proc
der einProc
(etwas, das einem Lambda ähnlich, aber nicht identisch ist) zurückgegeben wird, das beim Aufrufen mit einem Objekt als (erstem) Argument diename
Methode für dieses Objekt aufruft .Zweitens während
&
indef foo(&block) ... end
wandelt ein Block zu übergeben ,foo
um einenProc
, sie tut das Gegenteil , wenn sie einen aufgebrachtProc
.Es handelt sich also
&:name.to_proc
um einen Block, der ein Objekt als Argument verwendet und diename
Methode dafür aufruft , d{ |o| o.name }
. H.quelle
Hier
:name
ist das Symbol, das auf die Methodename
des Tag-Objekts verweist. Wenn wir zu gehen&:name
,map
wird esname
als Proc-Objekt behandelt. Kurz gesagt,tags.map(&:name)
fungiert als:quelle
es bedeutet
quelle
Es ist das gleiche wie unten:
quelle