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:
class Apple
TYPES = %w(red green yellow)
def each
yield TYPES.pop until TYPES.empty?
end
end
a = Apple.new
for i in a do
puts i
end
yellow
green
red
=> nil
E agora o cada iterador:
a = Apple.new
a.each do |i|
puts i
end
yellow
green
red
=> nil
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).