Encontré este código en un RailsCast :
def tag_names
@tag_names || tags.map(&:name).join(' ')
end
¿Qué significa el (&:name)en map(&:name)?
ruby
syntax
operators
parameter-passing
collimarco
fuente
fuente

Respuestas:
Es taquigrafía para
tags.map(&:name.to_proc).join(' ')Si
fooes un objeto con unto_procmétodo, puede pasarlo a un método como&foo, que lo llamaráfoo.to_procy lo usará como bloque del método.El
Symbol#to_procmétodo fue agregado originalmente por ActiveSupport pero se ha integrado en Ruby 1.8.7. Esta es su implementación:fuente
&, es decirtags.map(&:name.to_proc).join(' ')Otra taquigrafía genial, desconocida para muchos, es
que es una abreviatura de
Al llamar
method(:foo), tomamos unMethodobjetoselfque representa sufoométodo, y lo usamos¶ indicar que tiene unto_procmétodo que lo convierte en aProc.Esto es muy útil cuando quieres hacer cosas sin estilo. Un ejemplo es verificar si hay alguna cadena en una matriz que sea igual a la cadena
"foo". Existe la forma convencional:Y existe la forma sin puntos:
La forma preferida debería ser la más legible.
fuente
array.each{|e| foo(e)}es aún más corto :-) +1 de todos modos&method?[1,2,3].map(&Array.method(:new))Es equivalente a
fuente
Si bien también tengamos en cuenta que el ampersand
#to_procmagic puede funcionar con cualquier clase, no solo Symbol. Muchos rubíes eligen definir#to_procen la clase de matriz:Ampersand
&funciona enviando unto_procmensaje en su operando, que, en el código anterior, es de la clase Array. Y desde que definí el#to_procmétodo en Array, la línea se convierte en:fuente
Es taquigrafía para
tags.map { |tag| tag.name }.join(' ')fuente
&operador unario llamato_proca su operando. Por lo tanto, no es específico del método de mapa, y de hecho funciona en cualquier método que tome un bloque y pase uno o más argumentos al bloque.es lo mismo que
&:namesolo usa el símbolo como el nombre del método a llamar.fuente
La respuesta de Josh Lee es casi correcta, excepto que el código Ruby equivalente debería haber sido el siguiente.
no
Con este código, cuando
print [[1,'a'],[2,'b'],[3,'c']].map(&:first)se ejecuta, Ruby divide la primera entrada[1,'a']en 1 y 'a' para darobj1 yargs*'a' para causar un error ya que el objeto Fixnum 1 no tiene el método self (que es: primero).Cuando
[[1,'a'],[2,'b'],[3,'c']].map(&:first)se ejecuta;:firstes un objeto Symbol, por lo que cuando&:firstse le da un método de mapa como parámetro, se invoca Symbol # to_proc.map envía un mensaje de llamada a: first.to_proc con el parámetro
[1,'a'], por ejemplo,:first.to_proc.call([1,'a'])se ejecuta.El procedimiento to_proc en la clase Symbol envía un mensaje de envío a un objeto de matriz (
[1,'a']) con el parámetro (: primero), por ejemplo,[1,'a'].send(:first)se ejecuta.itera sobre el resto de los elementos en el
[[1,'a'],[2,'b'],[3,'c']]objeto.Esto es lo mismo que ejecutar
[[1,'a'],[2,'b'],[3,'c']].map(|e| e.first)expresión.fuente
[1,2,3,4,5,6].inject(&:+)- Inyectar espera una lambda con dos parámetros (MEMO) y el tema y:+.to_proclo entrega -Proc.new |obj, *args| { obj.send(self, *args) }o{ |m, o| m.+(o) }Aquí están sucediendo dos cosas, y es importante comprender ambas.
Como se describe en otras respuestas, el
Symbol#to_procse llama método.Pero la razón por la que
to_procse llama al símbolo es porque se pasamapcomo un argumento de bloque. Colocar&delante de un argumento en una llamada a un método hace que se pase de esta manera. Esto es cierto para cualquier método de Ruby, no solomapcon símbolos.El
Symbolse convierte en aProcporque se pasa como un bloque. Podemos mostrar esto tratando de pasar un proceso.mapsin el signo y:Aunque no es necesario convertirlo, el método no sabrá cómo usarlo porque espera un argumento de bloque. Pasarlo con
&da.mapel bloqueo que espera.fuente
(&: name) es la abreviatura de (&: name.to_proc) es igual que
tags.map{ |t| t.name }.join(' ')to_proc se implementa realmente en C
fuente
mapa (&: nombre) toma un objeto enumerable (etiquetas en su caso) y ejecuta el método de nombre para cada elemento / etiqueta, generando cada valor devuelto por el método.
Es una abreviatura de
que devuelve la matriz de nombres de elementos (etiquetas)
fuente
Básicamente ejecuta la llamada al método
tag.nameen cada etiqueta de la matriz.Es una taquigrafía rubí simplificada.
fuente
Aunque ya tenemos excelentes respuestas, mirando desde la perspectiva de un principiante me gustaría agregar la información adicional:
Esto significa que está pasando otro método como parámetro a la función de mapa. (En realidad, está pasando un símbolo que se convierte en un proceso. Pero esto no es tan importante en este caso particular).
Lo importante es que tenga un
methodnombrenameque será utilizado por el método de mapa como argumento en lugar delblockestilo tradicional .fuente
Primero,
&:namees un atajo para&:name.to_proc, donde:name.to_procdevuelve unProc(algo que es similar, pero no idéntico a un lambda) que cuando se llama con un objeto como (primer) argumento, llama alnamemétodo en ese objeto.En segundo lugar, mientras que
&endef foo(&block) ... endconversiones un bloque pasa afooaProc, hace lo contrario cuando se aplica a aProc.Por lo tanto,
&:name.to_proces un bloque que toma un objeto como argumento y llama alnamemétodo sobre él, es decir{ |o| o.name }.fuente
Aquí
:nameestá el símbolo que apunta al métodonamede etiqueta de objeto. Cuando pasamos&:nameamap, se trataránamecomo un objeto proc. Para abreviar,tags.map(&:name)actúa como:fuente
significa
fuente
Es lo mismo a continuación:
fuente