Usage of ‘if’ versus ‘unless’ for Perl conditionals
What are some guidelines for the best use of if
versus unless
in Perl code? Are there strong reasons to prefer one or the other in some situations?
Solution 1:
In Perl Best Practices, the advice is to never use unless
. Personally, I think that's lunacy.
I use unless
whenever there's a simple condition that I would otherwise write as if( ! ... )
. I find the unless
version to be more readable, especially when used as a postfix:
do_something() unless $should_not_do_that;
I recommend avoiding unless
anytime things get more complicated, such as when you will have elsif
or else
blocks. (Fortunately, or perhaps unfortunately, depending on your perspective, there is no elsunless
)
Also, any time a conditional is a complex expression made up of other booleans. For example,
unless( $foo and !$bar )
Is pretty damn confusing, and does not have any advantage over the equivalent if
.
Solution 2:
Aside from one esoteric case1unless
is just syntactic sugar for if !
. It exists to allow you to write code that is clearer and more expressive. It should be used when it achieves this goal and shunned when it impairs it.
I find unless
to be most useful for flow control in loops. e.g.
while (<$fh>) {
next unless /\S/;
# ...
}
For simple negations I find it clearer than a negated if
-- it's easy to miss that leading !
when reading code.
unless ($condition) {
do_something();
}
if (!$condition) {
do_something();
}
But don't write unless ... else
, because that's just jarring.
In postfix form it provides a hint about what the expected path through the code is.
do_normal_thing() unless $some_unlikely_condition;
1) The last expression evaluated is different, which can affect the behavior of subs without an explicit
return
.Solution 3:
A rule of thumb is that 'unless' should probably be used infrequently.
It is particularly useful in the postfix form, e.g.:
delete_old_widgets() unless $old_widget_count == 0
Situations where you should never use unless:
- with a compound condition (and, or, not)
- with an else clause