Returning guards — I hate you!

Jan Filipowski
Jan Filipowski blog
1 min readDec 8, 2017

Yes, I really hate them. Just look at them:

def meaningful_method_name(a, b)
return if a.excluding?
return unless b.turbo_not_excluding?
# real behaviour
end

Ok, let’s replace them with no-premature return notation

def meaningful_method_name(a, b)
if a.excluding?
elsif !b.turbo_not_excluding?
else
# real behaviour
end
end

Or

def meaningful_method_name(a, b)
if !a.excluding? && b.turbo_not_excluding?
# real behaviour
end
end

Now you can see that this method has actually two levels of abstraction included — the actual behaviour and when this behaviour is expected. The latter should be treated as precondition — in perfect world as part of method signature, in less then perfects outside of this method. If you don’t want to use it’s behaviour in other circumstances — just don’t. If it’s guarding public method, available as API (like in gem) — don’t fail silently, use errors instead.

Usually the“real behaviour” will have another if’s to control flow — now you have nested ifs and you’re not even aware of it. You no longer have one refactoring step towards better code, but two steps. And what’s even more important — you don’t see the possibility.

--

--