2010-01-24 7 views
28

Por qué es que el siguiente código funciona muy bienRubí Imprimir Inyectar Do Sintaxis

p (1..1000).inject(0) { |sum, i| 
    sum + i 
} 

embargo, el siguiente código da un error

p (1..1000).inject(0) do |sum, i| 
    sum + i 
end 

warning: do not use Fixnums as Symbols 
in `inject': 0 is not a symbol (ArgumentError) 

En caso de que no sea equivalente?

Respuesta

34

El bloque escrito usando las llaves se une al método de inyección, que es lo que tu intención es, y funcionará bien.

Sin embargo, el bloque que está encapsulado en el bloque do/end se unirá al método p. Debido a esto, la llamada de inyección no tiene un bloque asociado. En este caso, Inject interpretará el argumento, en este caso 0, como un nombre de método para llamar a cada objeto. Bacuase 0 no es un símbolo que se puede convertir en una llamada a método, esto producirá una advertencia.

6

Esto se ve como un efecto de la diferencia en la unión entre do/extremo y soportes:

soportes, usado como que están por encima, se unirán a la última función, mientras encadenado hacer/extremo se unirá a la primera.

Creo que es una forma extraña de decirlo, pero básicamente la primera instancia es pasar el bloque a la función 'inyectar', mientras que el segundo está tratando de pasar el bloque al primer método 'p'.

+1

", mientras que el segundo es en realidad tratando de pasar el bloque con el primer método (1 ..1000). " Haz eso "al primer método' p' "y estás en lo correcto. – sepp2k

+0

Lo corrigí. se pasó por alto eso en el código de arriba a primera vista! – Pete

6

El problema es con el p al principio. Si omite estos verá que ambos funcionan bien:

# Works! 
[5, 6, 7].inject(0) do |sum, i| # Correctly binds to `inject`. 
    sum + i 
end 

# Works too! 
[5, 6, 7].inject(0) { |sum, i| # Correctly binds to `inject`. 
    sum + i 
} 

Pero esto no funcionará:

# Kablammo! "p" came first, so it gets first dibs on your do..end block. 
# Now inject has no block to bind to! 
p [5, 6, 7].inject(0) do |sum, i| # Binds to `p` -- not what you wanted. 
    sum + i 
end