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?
views:
253answers:
5In 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
.
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
Aside from one esoteric case1 unless
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 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
.
Though I understand the motivations for these sorts of questions I don't believe it's really sensible to boil down the use of something like unless
into concrete rules of thumb. This, like a lot of auxiliary syntax in Perl is provided as a minor convenience for programmers to help them articulate themselves clearer at their own discretion; I've seen as much said in more ways than one by the lead developers throughout "Programming Perl". There's no higher purpose or rationalization. I'm well aware this finesses the question, but the only constraint I'd impose on using it is to see that it serves its broader purpose of making the code clearer. If it does, then all is well. Recognizing whether code is understandable is intuitive in itself and can't be reduced to a large handful of overly generalized usage conditions concerning every nuance of the built-in modifiers/operators/overall syntax, and where constraints and guidelines are needed in large group projects I don't think it would make sense to split hairs this finely.
Just a personal opinion maybe, but I like to use Unless when the if condition would start with a !