Experimenting with the Perl
flip-flop operator (see under “Counting Variables”), I hit what looked
like an oddity.
Tip of the Trade: The flip-flop operator in Perl is quite useful for comparing arguments, but it does have some surprising quirks.
My understanding was that the flip-flop operator takes two arguments,
tests against the first one until it’s matched, then continues to return
true until the second one is matched, whereupon it returns false again. Rinse
and repeat.
So, here’s a piece of code:
while () { if ( /^w/ .. /^s+$/ ) { print "line: $_"; } else { print "notline: $_"; } }
and a piece of text to run it on:
these two are lines also these three are lines this isn't a line but these lines are both lines
What I expected to happen is as the text file describes. The first two
sets and the last one would all print as lines. The blank lines match
/^s+$/ so they should print as notlines; " this isn't a line"
doesn’t start with a word character, so it should also be a notline. However, when I
actually ran the code, only " this isn't a line" printed as a
notline. If I doubled up the blank lines in the text file, the second
of each was a notline.
It looked like the flip-flop operator wasn’t triggering the ‘else’ block
until the loop after it returned false. So I went to check out the Perl docs
(look for the ‘Range Operators’ section) and discovered this is correct (if
slightly weird!) behavior. You always get one ‘true’ even once the right
value has been matched.
To get the behavior I wanted, I had to change the left-hand side to
/w/ and the right-hand side to /n$. Each non-whitespace
line then triggered both sides, and each whitespace line
trigger only the right side.
Juliet Kemp has been messing around with Linux systems, for financial reward and otherwise, for about a decade. She is also the author of “Linux System Administration Recipes: A Problem-Solution Approach” (Apress, 2009).