2012-01-09 18 views
17

soy consciente de la forma abreviada de un mapa que se parece a:Rubí Mapa taquigrafía notación

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

me dijeron que esto es la abreviatura:

[1, 2, 3, 4].map{|i| i.to_s} 

Esto tiene mucho sentido. Mi pregunta es esta: parece que debería haber una manera más fácil de escribir:

[1, 2, 3, 4].map{|x| f.call(x)} 

para algún procedimiento f. Sé que la forma en que acabo de escribir no es tan larga para empezar, pero afirmo que tampoco es el ejemplo anterior para el que existe la taquigrafía. Este ejemplo simplemente parece el complemento del primer ejemplo: en lugar de llamar al método to_s de cada i, deseo llamar a f para cada x.

¿Existe una taquigrafía?

+0

¿Es 'f' un método existente que desea llamar? –

Respuesta

36

Por desgracia, esta notación abreviada (que llama "símbolo # to_proc") no tiene manera de pasar argumentos al método o bloque que está siendo llamado, por lo que ni siquiera se podía hacer lo siguiente:

array_of_strings.map(&:include, 'l') #=> this would fail 

PERO, está de suerte porque en realidad no necesita este atajo para hacer lo que está tratando de hacer. El signo puede convertir un Proc o Lambda en un bloque, y viceversa:

my_routine = Proc.new { |str| str.upcase } 
%w{ one two three }.map &my_routine #=> ['ONE', 'TWO', 'THREE'] 

Nota la falta de colon antes de my_routine. Esto se debe a que no queremos convertir el símbolo :my_routine en un proceso encontrando el método y llamando al .method, sino que queremos convertir el Proc my_routine en un bloque y pasarlo a map.

Sabiendo esto, incluso se puede asignar un método de Ruby orígenes:

%w{ one two three }.map &method(:p) 

El método method tomaría el método p y convertirlo en un Proc, y el & la convierte en un bloque que se pasa a map. Como resultado, cada artículo se imprime. Esto es el equivalente a esto:

%w{ one two three }.map { |s| p s } 
+3

Si bien es cierto, no estoy seguro de que OP se considere "afortunado" de tener que definir el bloque por separado para obtener una llamada de "mapa" "más corta". –

+5

@DaveNewton No creo que entiendas la pregunta. Parece que ya tiene un Proc o Lambda existente al que se refiere como 'f' en la pregunta. Él puede obtener lo que quiere con 'array.map (& f)', que en realidad es un personaje más corto de lo que intentó. – coreyward