2010-07-27 5 views
13

estoy aprendiendo Ruby y RoR en este momento, y me encontré con esto:¿Cuál es el sentido de "para x en y" en Ruby?

<% for post in @posts %> 

en el Rails guide. Yo había entendido que la forma idiomática de hacerlo en Ruby es con:

<% @posts.each do |post| %> 

Si hay una diferencia, entonces ¿qué es? Y si no hay una diferencia, ¿no sería mejor para la gente de Rails prescindir de las expresiones idiomáticas propias de Ruby (en lugar de esto, que a mí me parece más pitónico)?

Editar: me acaba de encontrar dos explicaciones contradictorias de este Tutorials Point: dice que son los mismos, excepto "un bucle no crea un nuevo ámbito para las variables locales", mientras que CS.Auckland.ac.NZ dice for es sólo sintáctica azúcar para el equivalente .each.

Edit2: Elfor ... in en cuestión era para el index.html.erb generado en app/views/posts por script/generate scaffold. Hice una comprobación rápida y ahora genera la sintaxis .each. Supongo que esa parte de la guía se escribió en una etapa anterior del desarrollo de rieles cuando el andamio generó for ... in.

Edit3: ahora puedo confirmar que for x in y se utilizó en Rails 2.2.2, 2.3.8, sino por el uso que se y.each do |x|. Solo para que sepas.

Respuesta

21

La página de tutorial es correcta, for es equivalente a each excepto por la diferencia de alcance. Aquí hay una demostración:

arr = [1,2,3] 
arr.each do |x| 
    last = x 
end 
last # NameError 

vs.

arr = [1,2,3] 
for x in arr 
    last = x 
end 
last #=> 3 

Si desea hacer que funcione utilizando each, que tiene que hacer last = nil antes del bucle. Esto es, como se señaló en el enlace, porque los bloques comienzan un nuevo alcance, mientras que for no.

Sin embargo, tenga en cuenta que esto rara vez hace una diferencia práctica y pocas personas son conscientes de ello.

Cuando la gente utiliza for en rubí es más a menudo porque eso es lo que están acostumbrados procedentes de otros idiomas - no a causa de las diferencias entre for y each.

+0

¡Gracias! Exactamente lo que estaba buscando. Esto me lleva de regreso a mi punto original, ¿por qué el equipo Rails (o al menos quien escribió la guía Getting Started) iba con la sintaxis 'for ... in'? – Skilldrick

+2

Hay mucha gente que aprende rails sin haber aprendido ruby ​​primero. Supongo que la guía está escrita en un estilo que pretende ser familiar para las personas que provienen de otros idiomas. – sepp2k

+0

Una diferencia relacionada entre los dos que no es obvia solo de ese ejemplo: 'a = []; para x en [1,2,3,4]; un << proc {x} final; map (&: call) 'da' [4,4,4,4] 'mientras que el equivalente con' each' daría '[1,2,3,4]' porque 'each' introduce un nuevo enlace' x' con cada iteración. – Chuck

0

El caso es que el primer ejemplo (for post in @posts) parece más "procedural", mientras que el segundo (@posts.each do |post|) parece más "funcional". Desafortunadamente, la forma de procedimiento para leer el código aún se considera más popular, más clara y menos "geek". Es por eso que, tal vez, muchos preferirían la forma "nativa" de iterar a través de contenedores.

Si parece pitónico (no estoy seguro de si es cierto), entonces se puede considerar incluso mejor, ya que mejora el acceso de los Rails por parte de los desarrolladores que provienen de otras plataformas.

Personalmente, me gustaría que se empujen rubíes y formas "funcionales". Pero las razones anteriores demuestran que se puede hacer de cualquier manera.

+0

Digo que parece pitónico porque 'for ... in' es la forma estándar de iterar en Python. – Skilldrick

+1

@skill, así como también es una forma estándar de iterar en otros idiomas (sintaxis Perl obsoleta, por ejemplo). También es la forma * natural * (en el sentido en que lo humano lo hace) de iterar a través de cualquier colección. –

+0

sí, entiendo lo que quieres decir. No estaba necesariamente diciendo que estaban copiando Python, solo que se parece más a Python. – Skilldrick

0

Algún día estaba desarrollando la función de generar informes PDF para el sitio web en el que estaba trabajando.

El complemento que estaba usando tiene muchas limitaciones. Esas limitaciones me forzaron a producir la solución que era muy imperativa y de procedimiento. Estaba usando construcciones como while o for solo para enfatizar este estilo de programación.

De hecho, esta fue la única situación cuando utilicé esas palabras clave en ruby.

0

Es posible que desee utilizar for x in y si está tratando de hacer perfiles ruby ​​y su versión de ruby-prof no tiene method elimination.

0

Una cosa más sobre for x in y es que se puede hacer for i in 1..5 que funcionará como un estándar para el bucle, a partir de i = 1 y pasando por i = 5.

Lo práctico de esto es que se puede utilizar como una gama 3..8 o x..y, no está atascado empezando desde cero, lo que sería mediante el uso de n.times método.

+0

No 1.upto (5) .each {| x | # algo} ¿te ocupas de eso? – graydot

+0

@jeba ya sería. Soy relativamente nuevo en rubí, así que no había visto eso antes. ¡Así que gracias! ¡Aprendo algo nuevo cada día! –

+2

También puede hacer '(1..5) .each' – Skilldrick

Cuestiones relacionadas