Ruby Academy · Lesson

Guard Clauses

Clean early returns.

Lesson 4 of 413 steps

Guard Clauses is a free Ruby Academy lesson on CoddyKit. This is lesson 4 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Ruby Academy learning path, and your progress syncs across the web and the CoddyKit app. The Ruby Academy course includes 4 lessons in total.

Clean Early Returns

A guard clause is a check at the top of a method that returns early for invalid or edge cases. It keeps the main logic flat and easy to read.

def greet(name)
  return "Hello, stranger" if name.nil?
  "Hello, #{name}"
end
puts greet(nil)
puts greet("Ada")

The Problem: Deep Nesting

Without guards, validations pile up as nested if blocks. The real work ends up buried deep on the right edge of the screen.

def charge(user)
  if user
    if user[:active]
      puts "Charging #{user[:name]}"
    end
  end
end
charge({ name: "Sam", active: true })

The Fix: Guard Clauses

Flip each condition and return early. The happy path now lives at the base indentation level, unindented and obvious.

def charge(user)
  return unless user
  return unless user[:active]
  puts "Charging #{user[:name]}"
end
charge({ name: "Sam", active: true })

return with No Value

A bare return exits the method and yields nil. Use it when the caller does not need a result for the rejected case.

def log(message)
  return if message.nil? || message.empty?
  puts "LOG: #{message}"
end
log("")
log("started")

Returning a Value

A guard can also return a meaningful value, such as a sensible default, so callers always get something usable.

def discount(price)
  return 0 if price <= 0
  price * 0.1
end
puts discount(-5)
puts discount(200)

Guard with unless

return unless condition reads as 'bail out if this requirement is not met.' It is one of the most common Ruby idioms.

def withdraw(balance, amount)
  return "Insufficient funds" unless balance >= amount
  "New balance: #{balance - amount}"
end
puts withdraw(100, 150)
puts withdraw(100, 40)

Multiple Guards

Stack several guards to validate inputs one by one. Each line states a single rule, making the method self-documenting.

def register(name, age)
  return "Name required" if name.to_s.empty?
  return "Must be 18+" if age < 18
  "Registered #{name}"
end
puts register("", 30)
puts register("Lee", 16)
puts register("Lee", 21)

Guards with next in Loops

Inside a block or loop you cannot return just one iteration. Use next as a guard to skip to the next item.

[1, -2, 3, -4].each do |n|
  next if n.negative?
  puts n
end

Guards Improve Readability

Compare the two styles below mentally: guards remove the else and reduce indentation. Readers see invalid cases handled first, then the core logic.

def area(width, height)
  return 0 unless width.positive? && height.positive?
  width * height
end
puts area(0, 5)
puts area(4, 5)

Raising in a Guard

When a bad input is a programmer error rather than an expected case, raise an exception in the guard to fail fast and loud.

def sqrt(n)
  raise ArgumentError, "n must be >= 0" if n.negative?
  Math.sqrt(n)
end
puts sqrt(16)
puts sqrt(-1) rescue puts "caught negative input"

Putting It Together

Guard clauses are a small habit with a big payoff:

  • Handle edge cases up front and return.
  • Keep the main logic unindented.
  • Use return/next/raise as the situation demands.
def initials(name)
  return "" if name.nil? || name.strip.empty?
  name.split.map { |part| part[0].upcase }.join
end
puts initials("  ").inspect
puts initials("grace hopper")

Quick Check

Test your understanding of guard clauses.

Recap

You learned guard clauses:

  • Return early for invalid or edge cases.
  • return unless bails when a requirement is not met.
  • Use next to skip a loop iteration, raise for true errors.
  • The result is flat, self-documenting methods.
def safe_divide(a, b)
  return nil if b.zero?
  a / b
end
puts safe_divide(10, 0).inspect
puts safe_divide(10, 2)
Free to start

Learn Ruby with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
29
Lessons
109

Frequently Asked Questions

Is the “Guard Clauses” lesson free?

Yes — any 3 lessons of the Ruby Academy learning path, including “Guard Clauses”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Ruby Academy course includes 4 lessons in total.

What will I learn in “Guard Clauses”?

Clean early returns. You practise Ruby Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Ruby Academy?

No prior experience is required. Ruby Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 4 of 4.

How long does the “Guard Clauses” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Ruby Academy lesson?

Yes. Every Ruby Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. if, unless, ternary
  2. case/when Expressions
  3. Truthiness in Ruby
  4. Guard Clauses
← Back to Ruby Academy