Repetição e iteração em Ruby
Repetição é a ideia de executar um mesmo bloco de código várias vezes, normalmente até atingir uma condição (parar quando algo acontecer) ou para percorrer uma coleção (processar cada item de uma lista). Em Ruby, você pode fazer isso com loops clássicos (while e until) e com iteradores (times, each), que são muito usados por deixarem o código mais legível e com menos “estado” para acompanhar.
Uma regra prática: use each/times quando você estiver iterando sobre uma coleção ou um intervalo conhecido; use while/until quando a repetição depende de uma condição que muda ao longo do tempo (por exemplo, “enquanto ainda houver itens para processar”).
Loop com while: repete enquanto a condição for verdadeira
while executa o bloco repetidamente enquanto a condição for verdadeira. É útil quando você controla uma variável que muda a cada passo (contador, índice, saldo, tentativas, etc.).
Exemplo: contagem simples (com passo a passo)
Objetivo: imprimir números de 1 a 5.
- Passo 1: criar um contador inicial.
- Passo 2: repetir enquanto o contador não ultrapassar o limite.
- Passo 3: atualizar o contador dentro do loop (para não ficar infinito).
contador = 1
while contador <= 5
puts contador
contador += 1
endPontos de atenção: se você esquecer o contador += 1, a condição pode nunca mudar e o loop vira infinito.
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
Exemplo: processar uma lista por índice (quando faz sentido)
Embora Ruby prefira each para listas, às vezes você precisa do índice (ou quer controlar o avanço manualmente). Nesse caso, while com índice é uma opção clara.
nomes = ["Ana", "Bruno", "Carla"]
i = 0
while i < nomes.length
puts "Olá, #{nomes[i]}"
i += 1
endLoop com until: repete até a condição ficar verdadeira
until é o “inverso” do while: ele repete enquanto a condição for falsa e para quando a condição se torna verdadeira. Ele pode deixar o código mais natural quando você pensa em “parar quando X acontecer”.
Exemplo: contar até atingir um alvo
pontos = 0
until pontos >= 10
pontos += 2
end
puts pontos # 10Esse estilo costuma ficar mais legível do que negar uma condição em um while (por exemplo, while pontos < 10 também funcionaria). Escolha o que ficar mais claro para quem lê.
Iterador times: repetir um número fixo de vezes
times é um iterador muito comum quando você sabe exatamente quantas repetições quer. Ele evita o padrão “contador + while” e reduz chance de erro.
Exemplo: repetir 3 vezes
3.times do
puts "Processando..."
endExemplo: usar o índice gerado pelo times
times pode fornecer um índice começando em 0.
5.times do |i|
puts "Índice: #{i}"
endConstrução incremental de resultado com times (passo a passo)
Objetivo: construir uma string com 4 caracteres “#”.
- Passo 1: iniciar o acumulador (resultado) vazio.
- Passo 2: repetir 4 vezes.
- Passo 3: a cada repetição, acrescentar um “#”.
barra = ""
4.times do
barra << "#"
end
puts barra # "####"Esse padrão (acumulador + iteração) é muito usado para construir strings, listas e somatórios.
Iterador each: percorrer coleções no estilo Ruby
each é o iterador padrão para percorrer arrays e outras coleções. Ele expressa diretamente a intenção: “para cada item, faça algo”. Isso costuma ser mais legível do que controlar índices manualmente.
Exemplo: processar uma lista de nomes
nomes = ["Ana", "Bruno", "Carla"]
nomes.each do |nome|
puts "Olá, #{nome}!"
endExemplo: somar valores (acumulador)
valores = [10, 20, 5]
soma = 0
valores.each do |v|
soma += v
end
puts soma # 35Exemplo: filtrar itens manualmente (construção incremental)
Você pode construir um novo array adicionando apenas os itens que passam por uma regra. (Mais adiante, você verá métodos como select, mas aqui o foco é entender a iteração.)
numeros = [1, 2, 3, 4, 5, 6]
pares = []
numeros.each do |n|
if n.even?
pares << n
end
end
p pares # [2, 4, 6]each com with_index (quando você precisa do índice)
Em vez de usar while com índice, muitas vezes dá para manter o estilo Ruby com with_index.
nomes = ["Ana", "Bruno", "Carla"]
nomes.each_with_index do |nome, i|
puts "#{i}: #{nome}"
endControlando o fluxo: break e next
Dentro de loops e iteradores, você pode controlar o fluxo com clareza usando:
break: interrompe a repetição imediatamente.next: pula para a próxima iteração (ignora o restante do bloco atual).
break: parar ao encontrar uma condição
Exemplo: percorrer números e parar quando encontrar o primeiro múltiplo de 7.
encontrado = nil
(1..100).each do |n|
if (n % 7).zero?
encontrado = n
break
end
end
puts encontrado # 7Note o uso de um acumulador (encontrado) para guardar o resultado antes de sair do loop.
next: pular itens que não interessam
Exemplo: somar apenas números positivos.
numeros = [3, -2, 10, 0, -5]
soma = 0
numeros.each do |n|
next if n <= 0
soma += n
end
puts soma # 13Como evitar loops infinitos e estados difíceis de acompanhar
Checklist de segurança para while/until
- Garanta que a condição pode mudar: a variável usada na condição deve ser atualizada dentro do loop.
- Prefira condições simples e diretas (evite dupla negação e expressões muito longas).
- Se houver risco de “nunca terminar”, adicione um limite (por exemplo, número máximo de tentativas).
Exemplo: limite de tentativas com while
tentativas = 0
max_tentativas = 3
sucesso = false
while tentativas < max_tentativas
tentativas += 1
# ... executa uma ação que pode falhar
# sucesso = true se der certo
break if sucesso
endPreferindo iteradores para reduzir “estado”
Compare estes dois estilos para percorrer um array:
| Com índice manual | Com each |
|---|---|
| |
O segundo evita variáveis de controle (i), reduz chance de erro e deixa mais explícita a intenção.
Escolhendo a ferramenta certa
- Use
timesquando a repetição é um número fixo de vezes. - Use
eachquando você quer percorrer itens de uma coleção. - Use
while/untilquando a repetição depende de uma condição que evolui (e você precisa controlar esse estado). - Use
breakpara sair cedo quando atingir um objetivo; usenextpara ignorar casos que não devem ser processados.