Back to Tutorials
refactoring6/8/2025

What are Guard Clauses?

code smellguard clauserefactoringruby
What are Guard Clauses?

I learned about guard clauses thanks to Rubocop, the super annoying yet awesome code analyzer. I started refactoring my code everywhere Rubocop told me a guard clause would be better.

Why would it be better? Because guard clauses are an awesome way to make a piece of code more succinct and understandable.

Code explains better than words, so let's take an example. Checkout the method below.

def my_method(variable)
  if variable == 'great'
    # do something great
  else
    return nil
  end
end

As you can see, this is a relatively common method where we check if the passed parameter matches our expectation. If that's the case, we 'do something great', if not we return nil.

In reality, we can write this code in only two lines with a guard clause. You see, guard clauses are named like this because they protect some code from running unless a condition is met. They are usually used to ensure that the parameters that were passed meet some criteria to avoid running into exceptions or other problems.

def my_method(variable)
  return nil unless variable == 'great'
  # do something great
end

Those examples were pretty simple so you could see how easy it is to use guard clauses. For more complex code, they can be used to prevent a bad code smell known as nested conditional. That's when a method has a bunch of conditions making it hard to read through it and understand the flow of execution.

To have an idea of what a nested conditional nightmare is, take a look at the code below. What do you think?

def pay(invoice)
  if invoice.paid?
    return nil
  else
    if invoice.delay_payment?
      invoice.set_delayed_payment_date
    else
      if invoice.amount > 1000
        invoice.trigger_manual_payment
      else
        invoice.pay
      end
    end
  end
end

I personally don't like it at all! It's hard to read and understand exactly what's going on. What about the alternative below?

def pay(invoice)
  return nil if invoice.paid?
  return invoice.set_delayed_payment_date if invoice.delay_payment?
  return invoice.trigger_manual_payment if invoice.amount > 1000
  invoice.pay
end

It's so much simpler and clearer! Whenever I can, I use guard clauses and I haven't looked back.

Give it a try, you won't regret it.

Comments

Loading comments...

Level Up Your Dev Skills & Income 💰💻

Learn how to sharpen your programming skills, monetize your expertise, and build a future-proof career — through freelancing, SaaS, digital products, or high-paying jobs.

Join 3,000+ developers learning how to earn more, improve their skills, and future-proof their careers.

What are Guard Clauses? | Devmystify