2012-03-29 6 views
39

Dada la siguiente matriz a:¿Cómo paso un argumento al método abreviado array.map?

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

¿Cómo lo hago:

a.map { |num| num + 1 } 

usando la notación abreviada:

a.map(&:+ 1) 

o:

a.map(&:+ 2) 

donde 1 y 2 son los argumentos?

+16

Hacer trampa: '[1, 2, 3, 4, 5] .map (&: siguiente) # => [2, 3, 4, 5, 6]' –

+0

Puede que le interese Ruby's [Enumerators] (http://www.ruby-doc.org/core-2.1.2/Enumerator.html). – alxndr

Respuesta

33

No puede hacerlo así. El operador & es para convertir símbolos en procs.

a = [1, 2, 3, 4, 5] 
puts a.map(&:to_s) # prints array of strings 
puts a.map(&:to_s2) # error, no such method `to_s2`. 

& es una abreviatura de to_proc:

def to_proc 
    proc { |obj, *args| obj.send(self, *args) } 
end 

Se crea y devuelve la nueva proc. Como puede ver, no puede pasar ningún parámetro a este método. Solo puede llamar al proceso generado.

+0

tiene razón: desde array.map (&: some_method) es abreviado para: clase Símbolo def to_proc proc {| obj, * args | obj.send (self, * args)} final final. ¿Cómo pasas en los * args? –

+0

@not_nil: no es así. Use bloque/proc normal. –

+2

@not_nil: Ruby no es compatible con el estilo sin puntos para todo lo que vaya más allá de 'Symbol # to_proc', porque carece de composición de funciones y currying. ¿Vienes de un fondo funcional? –

24

No puede hacerlo con map. Pero mira Facets 'Enumerable#map_send:

require 'facets' 
[1, 2, 3].map_send(:+, 1) 
#=> [2, 3, 4] 

la escritura de su propia aplicación es bastante sencillo:

module Enumerable 
    def map_send(*args) 
    map { |obj| obj.send(*args) } 
    end 
end 
0

Si realmente lo necesita, puede utilizar la biblioteca Ampex, pero no sé si aún se mantiene.

Cuestiones relacionadas