Guard Clauses vs. Nested Conditionals
Tags: ruby, beginners, fundamentals
Published: 2019-07-28 18:07:27

---
title: Guard Clauses vs. Nested Conditionals
cover_image: https://thepracticaldev.s3.amazonaws.com/i/d8xpbvn60lpbdoiuafft.jpg
canonical_url: https://anthonygharvey.com/ruby/guard_clauses_vs_nested_if_statements
published: true
description: What are Ruby guard clauses and why use them instead of nested if statements
tags: ruby, beginner, fundamentals
---

**TLDR**; a guard clause is a premature return (early exit) that "guards" against the rest of your code from executing if it's not necessary (based on criteria you specify).

---

Soon after I started my career as a Ruby on Rails developer I learned about guard clauses and how they can improve code readability.

Let's take a look at an example method with a standard `if/else` statement.

```ruby
def example_method(parameter)
  if parameter == true
    # awesome code here
  else
    return nil
  end
end
```

In this method we're doing something that's common: evaluating a parameter and:

- executing some code if our expectations are met **OR**
- executing some other code if our expectations are not met.

In this case:

- if the parameter is `true` we execute some "awesome code"
- if not, we just return `nil`

This method can be shortened to only two lines of code by using a guard clause.

```ruby
def example_method(parameter)
  return nil unless parameter == true #<-- guard clause
  # awesome code here
end
```

<a href='https://dev.to/anthonyharvey/ruby-if-unless-while-and-until-4f9a'>unless method</a>

This was as short example to illustrate the concept of a guard clause. Now let's look at an example where a guard clause can help eliminate a code smell: nested conditionals.

```ruby

def print_shipping_label(order)
  if order.outstanding_payments?
    nil
  else
    if order.address_incomplete?
      order.send_address_reminder
    else
      if order.standard_shipping?
        order.print_standard_shipping_label
      else
        order.print_priority_shipping_lable
      end
    end
  end
end
```

This code is hard to read and follow what's happening in my opinion (just look at how many levels of indention are in the nested `if/else` statements!)

## Refactoring Nested Conditionals Using Guard Clauses

We can use guard clauses to refactor the nested `if/else` statements and make the method more readable and easier to follow.

```ruby
def print_shipping_label2(order)
  return nil if order.outstanding_payments?
  return order.send_address_reminder if order.address_incomplete?
  return order.print_standard_shipping_label if order.standard_shipping?
  order.print_priority_shipping_label
end
```

I like guard clauses for these reasons, but you should use them where it makes sense for you and your team.

For example, some languages require explicit resource management and having a single exit point from a method would make sense to prevent memory leaks. However Ruby has <a href='https://blog.heroku.com/incremental-gc' target='_blank'>garbge collection</a> to automatically collect unused objects.

---

## Takeaway:

Guard clauses **guard** (protect) the rest of your code from executing if not necessary (based on certain criteria) and are placed at the top of a method.

## Resources:

1. <a href='https://www.refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html' target='_blank'>Refactoring.com - Replace Nested Conditional with Guard Clauses</a>
2. <a href='https://refactoring.guru/replace-nested-conditional-with-guard-clauses' target='_blank'>Refactoring.guru - Replace Nested Conditional with Guard Clauses</a>

_This article was originally published on <a href= 'https://anthonygharvey.com/ruby/guard_clauses_vs_nested_if_statements' target='_blank'>anthonygharvey.com</a> on July 28th, 2019._