2010-08-11 11 views
5

Vi un fragmento de código de rubí hoy.¿Cómo funciona esta magia de inyección de rubí?

[1,2,3,4,5,6,7].inject(:+) 

=> 28

[1,2,3,4,5,6,7].inject(:*) 

=> 5040

La inyección de aquí es muy diferente de los que he visto antes, como

[1,2,3,4,5,6,7].inject {|sum, x| sum + x} 

Sírvanse explicar cómo funciona?

+0

No sé si hay un nombre especial para él (si desea buscarlo en Google), que no sea 'Symbol # to_proc'. –

Respuesta

6

No hay magia, el símbolo (método) es solo uno de los parámetros posibles. Esto es de los documentos:

# enum.inject(initial, sym) => obj 
    # enum.inject(sym)   => obj 
    # enum.inject(initial) {| memo, obj | block } => obj 
    # enum.inject   {| memo, obj | block } => obj 

Nuestro caso es el segundo.

También puede volver a escribir con el bloque tradicional:

op = :+ # parameter of inject call 
[1,2,3,4,5,6,7].inject {|sum, x| sum.send(op, x)} # also returns 28 

(para responder a "¿cómo funciona" parte)

+0

No se puede encontrar información sobre el símbolo como parámetros aquí, http://ruby-doc.org/core/classes/Enumerable.html. El documento es demasiado antiguo ... –

+0

@Zifei Ese es el enlace a la versión 1.8.6. Consulte http://ruby-doc.org/ para obtener enlaces a otras versiones, sección API Core –

+1

Obtenlo, http://ruby-doc.org/core-1.8.7/classes/Enumerable.html. Gracias. –

1

Como se puede ver in the docs, inject puede tomar un bloque (como usted' re familiarizarse con) o un símbolo que representa el nombre de un operador binario. Es una abreviatura útil para operaciones ya definidas.

+1

Gracias, ruby ​​1.9 es dulce :) –

3

El: + es un symbol que representa el mensaje de adición. Recuerde que Ruby tiene un estilo Smalltalk donde casi todas las operaciones se realizan enviando un mensaje a un objeto.

Como se discutió en gran detalle here, (1..100).inject(&:+) es una sintaxis válida en versiones anteriores donde Rails ha agregado la extensión to_proc a Symbol.

La capacidad de pasar solo un símbolo en la inyección era nueva en 1.9 y backported into 1.8.7.

+0

Y, de hecho, esta técnica se conoce como "el símbolo (en) famoso >> valor: hackear" (http://blog.3plus4.org/2007/03/27/selectors-as -blocks /) en la comunidad Smalltalk: '(1..100) reduce: # +' –