example - ruby pass block as argument
Ruby Print Inject Do Syntax (3)
El bloque escrito con las llaves se une al método de inyección, que es su intención, 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, inyectar 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 pueda convertir en una llamada de método, esto producirá una advertencia.
¿Por qué es que el siguiente código funciona bien?
p (1..1000).inject(0) { |sum, i|
sum + i
}
Pero, 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)
¿No deberían ser equivalentes?
El problema es con la p
al principio. Si omites estos, verás 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
Esto parece un efecto de la diferencia en el enlace entre do / end y corchetes:
Los corchetes, utilizados como está arriba, se enlazarán a la última función encadenada, mientras que do / end 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 la segunda está intentando pasar el bloque al primer método "p".