There's nothing wrong with unless
Sure there is. And I spent a page and a half in PBP explaining precisely
what was wrong with it. In summary:
- unless is fine for simple conditionals.
- But it makes compound conditionals harder to understand (because, in
general, people are relatively poor at applying de Morgan's law
correctly).
- In particular it makes conditionals that include partial negations
very much harder to comprehend.
- Even conditionals that start out simple, don't always stay simple;
extra subconditions are often identified and handled during
maintenance or extension of code
The result is that (as PBP points out):
unless and until are inherently harder to maintain. In
particular, whenever a negative control statement is extended to include
a negative operator, it will have to be re-cast as a positive control,
which requires you to change both the keyword and the conditional....Not
only is that extra effort, it's error-prone effort. Reworking
conditionals in that way is an excellent opportunity to introduce new
and subtle bugs into your program....This kind of mistake is
unfortunately common, but fortunately very easy to avoid. If you never
use an unless or until, then you'll never have to
rewrite it as an if or while. Moreover, if your
control statements are always "positive", your code will generally be
more comprehensible to all readers, regardless of the complexity of its
logical expressions...
I don't proscribe unless because it's never
appropriate. I recommend against it because it's often eventually
inappropriate. Because, in all but the simplest cases, it ultimately
makes comprehension and maintenenance harder and provides an opportunity
for bugs to creep in as code is extended.
Now, you may not agree with that arguments or my conclusion, and that's fine. But it's not accurate to assert that I'm merely letting:
personal opinions slip in there
or to imply that I did not have carefully thought-out reasons for my advice.
Indeed, it's easy to demonstrate that the deprecation of unless was
not just personal opinion. If you examine the source code of my
modules that predate PBP, you will find many instances of unless. So,
until I sat down to examine and codify Perl best practice my personal opinion was apparently that
unless was fine. It was only after I reviewed the arguments for and
against, discussed the issue (vigorously and at length ;-) with my many
reviewers, examined the mistakes that I and many of my clients had made
using unless, and thought about the long-term implications of
deploying the construct, that I concluded it should not be used.
Of course, that still is a personal opinion—just like everything
else that everyone else ever says—but it a personal opinion based
on reasoned argument and extensive professional and pedagogical
experience.
On the other hand, your subsequent point that blind acceptance of my advice is contrary to the spirit of the book is perfectly valid. I spent the first chapter asking people to think about these issues, to evaluate my arguments, and then to decide for themselves. However, not everyone has the time, the will, or the capacity to do that, which is why I tried to make the advice as careful and conservative as possible, so that those who do adopt it wholesale will be unharmed by the suggestions I made.
By the way, to answer the original poster's original question, my suggestion would be:
while (my $line = <>) {
croak "I can't handle this crap! '$line'\n"
if $line !~ m{\A (foo|bar) }xms;
my $dumb_example = $1;
....
....
}
| [reply] [d/l] |
-
unless is fine for simple conditionals
I disagree, but the reason is rather subtle and my experience shows that most people just won't buy the explanation until they've personally been burned by it. I've seen quite a few people get burned by it by now, and I'm quite convinced.
The "not" that is implicit in "unless" is subtle enough that it can get "lost" when you are looking at code. I've seen several people (including myself) stare at code over and over trying to figure out what is going on because they mentally misplaced the too-subtle "not". The code does exactly the opposite of what they expect and they can look at it and break it down over and over and still not recover the missing "not".
Just a couple of days ago, someone asked one of those head-slap questions in the chatter box to which I responded "because 48 *is* less than 50". They had looked at this very simple code (one simple statement with one simple comparison) over and over and couldn't figure out what was wrong. In this case they hadn't even used "unless", but had started to use "unless" and then changed their mind and used "if" instead. The distinction between the two is so subtle that even after repeated attempts, they failed to notice their mistake.
This shows that not only shouldn't you use "unless" even for simple conditionals, but shouldn't even consider using "unless". (:
| [reply] |
| [reply] |
The "not" that is implicit in "unless" is subtle enough that it can get "lost" when you are looking at code.
I never had that problem. For me, the "not" cannot be lost, because without it it's not unless any more.
This shows that not only shouldn't you use "unless" even for simple conditionals, but shouldn't even consider using "unless".
No, it does not. That's an undue generalization. You may not advocate the banishment of a language construct as a general rule just because "quite a few" got "burned by it now". There's no count of those which never got burned by using 'unless', and which are quite comfortable using it as a statement modifier or a control construct in the sense perlsyn states:
"if" executes the statement once if and only if the condition is true. "unless" is the opposite, it executes the statement unless the condition is true (i.e., if the condition is false).
Subtleties in the english language regarding 'unless' are irrelevant and must not be stressed to daemonize it's use. After all, we're programming perl, not writing english statements.
--shmem
_($_=" "x(1<<5)."?\n".q·/)Oo. G°\ /
/\_¯/(q /
---------------------------- \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
| [reply] |
I, personally, would rather avoid using unless. It's a bit of a mind-twist as I grew up with C. Essentially it is if ( ! condition )
and, for me, it is often simpler to explicitly present the not.
In fact the very posting of this question obviates the fact that unless isn't straightforward to understand for some users.
Although I accept there are rare occasions when unless might make sense it is a keyword that is best avoided when aiming for maximal maintainability. | [reply] [d/l] [select] |
Oh, I agree that some people find it unclear, and that's fine. Personally, I prefer unless to if-not.
I was just objecting to the dogmatic interpretation of PBP, which seems to be antithetical to the book's point.
| [reply] |