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
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.