views:

253

answers:

5

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?

+19  A: 

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.

friedo
I don't think `unless` need be automatically avoided for complex expressions. `if (!($foo and !$bar))` isn't necessarily clearer and the programmer shouldn't have to (and may not want to) apply DeMorgan's Theorem to get the cleaner `if (!$foo or $bar)`.
Michael Carman
+1 for mentioning Perl Best Practices, and elsunless.
Matthew J Morrison
@Michael The problem with not applying DeMorgan's Theorem is that the next programmer to come along will have to apply it in his head when he reads the code. I ran across this at work recently with a bit of code like `unless ($obj->has_errors || !$obj->is_valid) { return 1 } # error handling code follows` Or in English "If the prior actions on the object were not not successful don't run the error handling code."
Ven'Tatsu
+8  A: 

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
Grant McLean
+11  A: 

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.

Michael Carman
+1 Great point about implicit returns.
friedo
Sometimes I find the negation reads more clearly if the keyword 'not' is used rather than '!', e.g.: get_ready() if not $ready;
Grant McLean
Absolutely great response. `unless` exists to improve readability. Remember that and everything else follows.
daotoad
A: 

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.

cikkle
A: 

Just a personal opinion maybe, but I like to use Unless when the if condition would start with a !

David Brunelle