Control Flow: if, unless, loops

· 12 min read · beginner
control-flow if unless loops beginner

Control flow is the backbone of any program. It determines which code runs, how many times it runs, and in what order. In this tutorial, you will learn how to make decisions with conditionals and repeat actions with loops in Ruby.

By the end of this guide, you will be comfortable using if, unless, case, while, until, and Ruby’s powerful iterator methods.

The if Statement

The if statement is Ruby’s primary way to make decisions. It executes code only when a condition evaluates to true.

temperature = 25

if temperature > 30
  puts "It's hot outside!"
elsif temperature > 20
  puts "It's a nice day"
elsif temperature > 10
  puts "It's a bit chilly"
else
  puts "It's cold outside"
end

The condition does not need parentheses, though you can use them for complex expressions. Ruby treats everything except nil and false as truthy.

One-Line if

Ruby lets you write simple conditionals on a single line:

puts "You can vote!" if age >= 18

This is called a modifier and is useful for short, simple conditions.

The unless Statement

unless is the opposite of if. It executes code when the condition is false.

password = "secret123"

unless password.length >= 8
  puts "Password is too short"
end

You can also use unless with else, though it reads less naturally:

unless user.active?
  puts "Please activate your account"
else
  puts "Welcome back!"
end

When to Use unless

Use unless when checking for negative conditions or validating input. It makes your code read more naturally than nested if !condition statements.

The case Statement

When you need to compare one value against multiple options, case is cleaner than multiple elsif branches.

grade = "B"

case grade
when "A"
  puts "Excellent!"
when "B"
  puts "Good job!"
when "C"
  puts "Passed"
when "D", "F"  # Multiple values in one when clause
  puts "Need improvement"
else
  puts "Invalid grade"
end

Case with Ranges

You can use ranges in when clauses for numeric comparisons:

score = 85

case score
when 90..100
  puts "A"
when 80..89
  puts "B"
when 70..79
  puts "C"
else
  puts "Need improvement"
end

Case as an Expression

Unlike some languages, case in Ruby returns a value you can assign:

status = case http_code
         when 200 then "OK"
         when 404 then "Not Found"
         when 500 then "Server Error"
         else "Unknown"
         end

While Loops

The while loop repeats as long as its condition is true:

count = 1

while count <= 5
  puts "Count: #{count}"
  count += 1
end

Be careful with infinite loops — always ensure the condition will eventually become false.

Until Loops

until is the opposite of while — it repeats until the condition is true:

count = 1

until count > 5
  puts "Count: #{count}"
  count += 1
end

Choose whichever reads more naturally for your specific condition.

Iterator Methods

Ruby excels at iteration. Instead of traditional loops, Rubyists often use iterator methods.

times Iterator

The times method runs a block a specific number of times:

5.times do |i|
  puts "Iteration #{i + 1}"
end

# Or in one line:
5.times { |i| puts "Iteration #{i + 1}" }

each Iterator

The each method iterates over each element in a collection:

fruits = ["apple", "banana", "cherry"]

fruits.each do |fruit|
  puts "I like #{fruit}"
end

You also get the index with each_with_index:

fruits.each_with_index do |fruit, index|
  puts "#{index + 1}. #{fruit}"
end

upto and downto

For numeric ranges, upto and downto are useful:

1.upto(5) { |n| puts n }
5.downto(1) { |n| puts n }

Breaking and Skipping

break

The break keyword exits a loop immediately:

numbers = [1, 2, 3, 4, 5]

numbers.each do |n|
  break if n == 3
  puts n
end
# Output: 1, 2

next

The next keyword skips to the next iteration:

numbers = [1, 2, 3, 4, 5]

numbers.each do |n|
  next if n.odd?
  puts n
end
# Output: 2, 4

When to Use What

  • Use if for most conditional logic
  • Use unless for validation and negative conditions
  • Use case when comparing one value against multiple options
  • Use while/until when you need traditional loop behavior
  • Use iterator methods (each, times) when working with collections

Summary

You have learned the core control flow structures in Ruby:

  • if — Execute code based on a condition
  • unless — Execute code when a condition is false
  • case — Compare one value against multiple options
  • while — Loop while a condition is true
  • until — Loop until a condition is true
  • Iteratorstimes, each, upto, downto for clean iteration
  • break and next — Control loop flow

Practice these concepts to become comfortable with Ruby’s expressive control flow. In the next tutorial, you will learn about methods — how to define and call your own reusable blocks of code.