Acabei de fazer uma pergunta rápida sobre loops no Ruby. Existe uma diferença entre essas duas maneiras de iterar através de uma coleção?
# way 1
@collection.each do |item|
# do whatever
end
# way 2
for item in @collection
# do whatever
end
Basta saber se estes são exatamente os mesmos ou se talvez haja uma diferença sutil (possivelmente quando @collection
é nulo).
x
permanece no para cenário é devido ao fato de que (em geral) palavras-chave não criar novos escopos. se , a menos que , comece , por , enquanto etc. tudo funcione com o escopo atual.#each
no entanto aceita um bloco. Os blocos sempre adicionam seu próprio escopo sobre o escopo atual. Significando que declarar uma nova variável no bloco (portanto, um novo escopo) não será acessível de fora do bloco, pois esse escopo adicional não está disponível lá.Veja " Os males do loop for" para uma boa explicação (há uma pequena diferença considerando o escopo da variável).
O uso
each
é considerado um uso mais idiomático do Ruby.fonte
Seu primeiro exemplo,
é mais idiomático . Enquanto Ruby suporta construções de loop como
for
ewhile
, a sintaxe do bloco é geralmente preferida.Outra diferença sutil é que qualquer variável que você declara dentro de um
for
loop estará disponível fora do loop, enquanto as de um bloco iterador são efetivamente privadas.fonte
while
euntil
realmente tem alguns usos muito concretos que não podem ser substituídos por cada um, como por exemplo, gerar valores exclusivos ou para REPLs.Mais um diferente ..
fonte: http://paulphilippov.com/articles/enumerable-each-vs-for-loops-in-ruby
para mais claro: http://www.ruby-forum.com/topic/179264#784884
fonte
Parece que não há diferença,
for
usaeach
por baixo.Como diz Bayard, cada um é mais idiomático. Ele esconde mais de você e não requer recursos especiais de idioma. Por comentário de Telêmaco
for .. in ..
define o iterador fora do escopo do loop, portantofolhas
a
definidas após o término do loop. Onde comoeach
não. Qual é outro motivo a favor do usoeach
, porque a variável temp vive um período mais curto.fonte
for
não usaeach
por baixo. Veja outras respostas.Nunca usá-
for
lo pode causar erros quase não rastreáveis.Não se deixe enganar, não se trata de código idiomático ou de problemas de estilo. A implementação de Ruby
for
tem uma falha séria e não deve ser usada.Aqui está um exemplo em que
for
introduz um bug,Impressões
Usando
%w{foo bar quz}.each { |n| ... }
impressõesPor quê?
Em um
for
loop, a variáveln
é definida uma vez e somente e, em seguida, essa definição é usada para todas as iterações. Portanto, cada bloco se refere ao mesmon
que possui um valorquz
no momento em que o loop termina. Erro!Em um
each
loop, uma variável novan
é definida para cada iteração, por exemplo, acima da variáveln
é definida três vezes separadas. Portanto, cada bloco se refere a um separadon
com os valores corretos.fonte
Até onde eu sei, usar blocos em vez de estruturas de controle no idioma é mais idiomático.
fonte
Eu só quero fazer um ponto específico sobre o loop for in em Ruby. Pode parecer uma construção semelhante a outras linguagens, mas na verdade é uma expressão como qualquer outra construção em loop no Ruby. De fato, o for in funciona com objetos Enumerable, assim como o iterador de cada.
A coleção passada para for in pode ser qualquer objeto que possua um método para cada iterador. Matrizes e hashes definem cada método, e muitos outros objetos Ruby também. O loop for / in chama cada método do objeto especificado. Como esse iterador gera valores, o loop for atribui cada valor (ou cada conjunto de valores) à variável (ou variáveis) especificada e, em seguida, executa o código no corpo.
Este é um exemplo bobo, mas ilustra o ponto em que o loop for trabalha com QUALQUER objeto que possua um método each, assim como o iterador de cada um:
E agora o cada iterador:
Como você pode ver, ambos estão respondendo a cada método que gera valores de volta ao bloco. Como todos aqui declararam, é definitivamente preferível usar cada iterador no loop for. Eu só queria voltar para casa a ponto de não haver nada mágico no loop for in. É uma expressão que chama cada método de uma coleção e a passa para seu bloco de código. Portanto, é um caso muito raro que você precisaria usar para o in. Use o cada iterador quase sempre (com o benefício adicional do escopo do bloco).
fonte
No loop 'for', a variável local ainda permanece após cada loop. No loop 'each', a variável local é atualizada após cada loop.
fonte