Question

Ruby Loops: Alternatives to a do...while Loop in Ruby

rubyloops

Question

I want to repeatedly ask the user for names, store each non-empty name in an array, and stop when the user enters an empty string.

Here is my current Ruby code:

people = []
info = 'a' # initialize with a non-empty value so the loop runs at least once

while !info.empty?
  info = gets.chomp
  people << Person.new(info) unless info.empty?
end

This feels like a case for a do ... while loop, because I want the body to run once before checking the condition.

I tried writing it like this:

people = []

begin
  info = gets.chomp
  people << Person.new(info) unless info.empty?
end while !info.empty?

Ruby does not seem to support the do ... while syntax used in some other languages. What is the Ruby way to handle this pattern more cleanly, without needing to initialize info to a random value first?

Short Answer

By the end of this page, you will understand how Ruby handles loops that must run at least once. You will learn Ruby's begin ... end while form, the common loop do pattern with break, and how to write cleaner input-reading loops without fake initial values.

Concept

In some languages, a do ... while loop runs the code block first and checks the condition afterward. This is useful when the loop body must execute at least one time.

Ruby does not use the exact do ... while syntax, but it does support the same idea through:

  • begin ... end while
  • loop do ... break
  • reading input first, then checking whether to continue

This matters because many real programs need to:

  • ask for user input at least once
  • retry until valid input is entered
  • keep processing until a stop condition appears

A common beginner mistake is forcing a normal while loop to behave like a post-condition loop by giving a variable a fake initial value. That works, but it is not the clearest Ruby style.

In Ruby, the more idiomatic solution is usually one of these:

begin
  # code runs first
end while condition

or:

loop do
  # code runs
  break if stop_condition
end

Both patterns avoid unnecessary placeholder values and express your intent more clearly.

Mental Model

Think of a normal while loop like a security guard standing before a door:

  • The guard checks the condition first.
  • If the condition fails, you never enter.

A post-condition loop is like a guard standing after the room:

  • You always go in once.
  • After that, the guard decides whether you can go around again.

Your input example fits the second model:

  • ask for a name
  • if it is empty, stop
  • otherwise store it and repeat

So the important idea is not the exact words do ... while, but the behavior: run once, then decide whether to continue.

Take Quiz

Syntax and Examples

1. begin ... end while

Ruby supports a post-condition loop using begin ... end while.

people = []

begin
  info = gets.chomp
  people << Person.new(info) unless info.empty?
end while !info.empty?

Why this works

  • begin ... end runs first
  • while !info.empty? is checked after the block
  • the loop stops when the user enters an empty string

2. loop do with break

This is often the most idiomatic Ruby approach.

people = []

loop do
  info = gets.chomp
  break if info.empty?

  people << Person.new(info)
end

Why many Ruby developers prefer this

  • very readable
  • no fake initial value needed
  • stopping condition is easy to see

3. Simple example without Person

names = []

loop do
  name = gets.chomp
  break if name.empty?

  names << name
end

p names

If the user enters:

Alice
Bob

Then names becomes:

["Alice", "Bob"]

Step by Step Execution

Consider this Ruby code:

names = []

loop do
  name = gets.chomp
  break if name.empty?
  names << name
end

Now imagine the user types:

Alice
Bob

Step-by-step

  1. names = []

    • An empty array is created.
  2. loop do

    • Ruby starts an infinite loop.
    • It will keep running until break is reached.
  3. First iteration:

    • name = gets.chomp
    • User enters Alice
    • name is now "Alice"
    • break if name.empty?
    • "Alice".empty? is false, so continue
    • names << name
    • names becomes ["Alice"]
  4. Second iteration:

    • User enters Bob
    • name is now "Bob"
    • name.empty? is false
    • names << name
    • names becomes ["Alice", "Bob"]
  5. Third iteration:

    • User just presses Enter
    • gets.chomp returns ""
    • name.empty? is true
    • break stops the loop
  6. Final result:

["Alice", "Bob"]

This pattern is easy to trace because the exit condition is checked immediately after reading input.

Real World Use Cases

This pattern appears often in Ruby programs.

User input collection

emails = []

loop do
  email = gets.chomp
  break if email.empty?
  emails << email
end

Used in small CLI tools, setup scripts, or interview exercises.

Retry until valid input

age = nil

loop do
  print "Enter your age: "
  input = gets.chomp

  if input.match?(/^\d+$/)
    age = input.to_i
    break
  end

  puts "Please enter a valid number."
end

Used in terminal apps and admin scripts.

Reading lines until a sentinel value

lines = []

loop do
  line = gets.chomp
  break if line == "STOP"
  lines << line
end

Useful when processing text input until a special command appears.

Menu-driven programs

loop do
  puts "1. Add"
  puts "2. Exit"
  choice = gets.chomp

  break if choice == "2"
  puts "You chose: #{choice}"
end

Common in beginner Ruby console applications.

Take Quiz

Real Codebase Usage

In real Ruby projects, developers usually pick the loop form that best matches the task.

Common pattern: guard clause with break

loop do
  input = gets.chomp
  break if input.empty?

  process(input)
end

This is clean because the stop condition is handled early.

Validation before object creation

users = []

loop do
  name = gets.chomp.strip
  break if name.empty?

  users << User.new(name: name)
end

This avoids creating invalid objects from empty input.

Using until for opposite logic

Sometimes Ruby code expresses the condition in reverse:

begin
  input = gets.chomp
  puts "You typed: #{input}"
end until input == "quit"

This works, but many teams still prefer loop do plus break because it is straightforward.

Error handling inside loops

loop do
  input = gets.chomp
  break if input.empty?

  begin
    people << Person.new(input)
  rescue StandardError => e
    puts "Could not create person: #{e.message}"
  end
end

This style is useful when each iteration may fail independently.

Why loop do is common

  • clear start and stop behavior
  • easy to combine with next, break, and validation
  • avoids awkward setup code before the loop

Common Mistakes

1. Using a fake initial value just to start the loop

This works, but it is usually less clear:

info = "a"
while !info.empty?
  info = gets.chomp
end

Better

loop do
  info = gets.chomp
  break if info.empty?
end

2. Creating objects before checking for empty input

Broken version:

loop do
  info = gets.chomp
  people << Person.new(info)
  break if info.empty?
end

Problem

This creates Person.new("") when the user presses Enter.

Better

loop do
  info = gets.chomp
  break if info.empty?
  people << Person.new(info)
end

3. Confusing not with !

Ruby allows both:

not info.empty?
!info.empty?

But ! is more common and often clearer in conditions.


4. Typo in variable names

The original example showed both Copypeople and people.

Broken version:

Copypeople = []
people << Person.new(info)

Problem

You are using two different variable names.

Better

people = []

Use one consistent local variable name.


5. Using a constant accidentally

In Ruby, names starting with a capital letter are constants.

People = []

That is not the same as a normal local variable.

Better

people = []

Use lowercase for local variables.


6. Forgetting chomp

Without chomp, pressing Enter leaves a newline in the string.

input = gets

Then input.empty? may not behave as expected because the string contains "\n".

Better

input = gets.chomp

Comparisons

ApproachRuns at least once?Idiomatic in Ruby?Best use
while conditionNoYesWhen you can check before entering
begin ... end while conditionYesValid, less commonWhen you want true post-condition behavior
loop do ... breakYesVery commonInput loops, validation, repeated actions
until conditionNoYesWhen logic reads better as “keep going until”
begin ... end until conditionYesValidPost-condition loop with reversed logic

Example comparison

while

info = gets.chomp
while !info.empty?
  people << Person.new(info)
  info = gets.chomp
end

This can work, but it forces one read before the loop.

begin ... end while

begin
  info = gets.chomp
  people << Person.new(info) unless info.empty?
end while !info.empty?

This matches the idea of a classic post-condition loop.

loop do

loop do
  info = gets.chomp
  break if info.empty?
  people << Person.new(info)
end

This is often the clearest Ruby version.

not vs !

FormMeaningNotes
!valuelogical negationmost common in conditions
not valuelogical negationvalid, but lower precedence can be confusing
Take Quiz

Cheat Sheet

Post-condition loops in Ruby

Ruby does not use do ... while

Use one of these instead:

begin
  # code
end while condition
loop do
  # code
  break if condition
end

Best pattern for user input

items = []

loop do
  input = gets.chomp
  break if input.empty?
  items << input
end

Useful rules

  • while checks the condition first
  • begin ... end while checks after running once
  • loop do runs forever until break
  • use break to stop a loop do
  • use next to skip to the next iteration
  • use chomp to remove the trailing newline from input

Common checks

input.empty?
input == "quit"
input.strip.empty?

Watch out for

  • fake initial values like info = "a"
  • creating objects before checking for blank input
  • capitalized variable names, which become constants
  • forgetting chomp

Clean pattern with object creation

people = []

loop do
  name = gets.chomp
  break if name.empty?
  people << Person.new(name)
end

FAQ

Is there a do ... while loop in Ruby?

Not with that exact syntax. Ruby uses begin ... end while for post-condition loops.

What is the Ruby equivalent of do ... while?

The closest equivalent is:

begin
  # code
end while condition

Many Ruby developers also use loop do with break.

Which is more idiomatic in Ruby: begin ... end while or loop do?

Both are valid, but loop do with break is more commonly seen in Ruby code.

Why not just use while?

A while loop checks the condition before the first iteration. If you need the loop body to run at least once, while alone is awkward.

Why should I use chomp with gets?

gets includes the newline character from pressing Enter. chomp removes it so empty input becomes "".

Should I use not or ! in Ruby conditions?

! is usually preferred because it is shorter and avoids precedence confusion.

How do I stop when the user enters only spaces?

Use strip.empty? instead of empty?:

break if input.strip.empty?
Take Quiz

Mini Project

Description

Build a small Ruby console program that collects task names from the user until they press Enter on a blank line. This demonstrates the Ruby way to write a loop that must run at least once, while also practicing array building and input validation.

Goal

Create a program that repeatedly accepts task names and stores them in an array until the user enters a blank line.

Requirements

  1. Start with an empty array for tasks.
  2. Repeatedly ask the user to enter a task.
  3. Stop when the user enters a blank line.
  4. Store only non-empty task names.
  5. Print the final list of tasks at the end.
Take Quiz

Keep learning

Related questions

View more