Refactoring using guard clauses
This post is almost purely about code style, but it’s an approach to coding and refactoring that I just found and really enjoy for its simplicity and readability.The secret sauce to this approach is called a guard clause.
Say I have a method that I’m writing where I want to return one thing is a condition is true, another thing if it’s false. The way I used to write the code is exactly how I wrote that sentence:
def do_something_conditionally(fact)
if fact == true
fact
else
false
end
end
Pretty standard, right? Now check out the same example with a guard clause:def do_something_conditionally(fact)
return false unless fact == true
fact
end
We saved a couple lines of code, which is nice (although I could’ve saved more turning the conditional into ternary (fact == true ? fact : false)). However, the big gain from doing it this way is that it’s easier to read. Disagree?It may help to have a more complex example, perhaps using nested conditionals:
def account_type
if has_problems?
type = "problems"
if is_past_due?
type = "past due"
if is_weeks_past_due?
type = "delinquent"
end
end
else
type = "normal"
end
type
end
…and now with guard clauses:def account_type
return "delinquent" if is_weeks_past_due?
return "past due" if is_past_due?
return "problems" if has_problems?
"normal"
end
We’ve saved more lines of code, this time something we could not have easily change to ternary, and it’s harder to argue that this isn’t more readable now.If all of that isn’t convincing enough, check out the quasi-official Ruby Style Guide, because it also recommends using guard clauses when possible.