Acabo de tener una pregunta rápida sobre los bucles en Ruby. ¿Hay alguna diferencia entre estas dos formas de iterar a través de una colección?
# way 1
@collection.each do |item|
# do whatever
end
# way 2
for item in @collection
# do whatever
end
Solo me pregunto si estos son exactamente iguales o si tal vez hay una sutil diferencia (posiblemente cuando @collection
es nula).
x
permanece en el escenario for se debe al hecho de que las palabras clave (en general) no crean nuevos ámbitos. Si , a menos , comenzar , para , mientras , etc. todo el trabajo con el ámbito actual.#each
Sin embargo acepta un bloqueo. Los bloques siempre agregan su propio alcance sobre el alcance actual. Lo que significa que declarar una nueva variable en el bloque (por lo tanto, un nuevo alcance) no será accesible desde fuera del bloque ya que ese alcance adicional no está disponible allí.Consulte " Los males del bucle for" para obtener una buena explicación (hay una pequeña diferencia considerando el alcance variable).
El uso
each
se considera un uso más idiomático de Ruby.fuente
Tu primer ejemplo
Es más idiomático . Si bien Ruby admite construcciones en bucle como
for
ywhile
, generalmente se prefiere la sintaxis de bloque.Otra diferencia sutil es que cualquier variable que declare dentro de un
for
bucle estará disponible fuera del bucle, mientras que aquellas dentro de un bloque iterador son efectivamente privadas.fuente
while
y enuntil
realidad tienen algunos usos muy concretos que no se pueden reemplazar con cada uno, como por ejemplo generar valores únicos o para REPL.Una más diferente ...
fuente: http://paulphilippov.com/articles/enumerable-each-vs-for-loops-in-ruby
para más claridad: http://www.ruby-forum.com/topic/179264#784884
fuente
Parece que no hay diferencia,
for
utilizaeach
debajo.Como dice Bayard, cada uno es más idiomático. Se esconde más de ti y no requiere características especiales de idioma. Por el comentario de Telémaco
for .. in ..
establece el iterador fuera del alcance del bucle, por lo quehojas
a
definidas una vez finalizado el ciclo. Donde comoeach
no. Cuál es otra razón a favor del usoeach
, porque la variable temporal vive un período más corto.fuente
for
no se usaeach
debajo. Ver otras respuestas.Nunca usarlo
for
puede causar errores casi imposibles de rastrear.No se deje engañar, no se trata de código idiomático o problemas de estilo. La implementación de Ruby
for
tiene una falla grave y no debe usarse.Aquí hay un ejemplo donde se
for
introduce un error,Huellas dactilares
Usando
%w{foo bar quz}.each { |n| ... }
impresiones¿Por qué?
En un
for
bucle, la variablen
se define una sola vez y luego se usa esa definición para todas las iteraciones. Por lo tanto, cada bloque se refiere al mismon
que tiene un valorquz
para cuando finaliza el ciclo. ¡Insecto!En un
each
bucle,n
se define una variable nueva para cada iteración, por ejemplo, arriba, la variablen
se define tres veces por separado. Por lo tanto, cada bloque se refiere a un separadon
con los valores correctos.fuente
Hasta donde sé, usar bloques en lugar de estructuras de control en lenguaje es más idiomático.
fuente
Solo quiero hacer un punto específico sobre el ciclo for in en Ruby. Puede parecer una construcción similar a otros lenguajes, pero de hecho es una expresión como cualquier otra construcción en bucle en Ruby. De hecho, for in funciona con objetos Enumerable al igual que cada iterador.
La colección pasada a for in puede ser cualquier objeto que tenga un método de cada iterador. Las matrices y los hash definen cada método, y muchos otros objetos Ruby también lo hacen. El bucle for / in llama a cada método del objeto especificado. A medida que ese iterador produce valores, el bucle for asigna cada valor (o cada conjunto de valores) a la variable (o variables) especificadas y luego ejecuta el código en el cuerpo.
Este es un ejemplo tonto, pero ilustra el punto de que el bucle for in funciona con CUALQUIER objeto que tenga cada método, tal como lo hace cada iterador:
Y ahora el cada iterador:
Como puede ver, ambos están respondiendo a cada método que devuelve valores al bloque. Como todos declararon aquí, definitivamente es preferible usar cada iterador sobre el ciclo for in. Solo quería llevar a casa el punto de que no hay nada mágico en el bucle for. Es una expresión que invoca cada método de una colección y luego lo pasa a su bloque de código. Por lo tanto, es un caso muy raro que necesitaría usar. Use cada iterador casi siempre (con el beneficio adicional del alcance del bloque).
fuente
En el ciclo 'for', la variable local sigue viva después de cada ciclo. En 'cada' bucle, la variable local se actualiza después de cada bucle.
fuente