SPUG: flip-flops
Michael R. Wolf
MichaelRunningWolf at att.net
Tue Feb 12 18:48:44 CST 2002
Matt Tucker <tuck at whistlingfish.net> writes:
[...]
> I've never seen just a bare '$' in Perl to indicate "last
> line". Do you have any documentation to support the
> existence of it? Regardless, doing the following gives the
> correct behavior:
>
> perl -n -e '$body .= $_ if /^$/ .. 0;' \
> -e '$head .= $_ if (1 .. /^$/);' \
> -e 'END{print $head, "\n", "="x40, "\n", $body;}'
You're right - dollar doesn't mean last line. Despite being
an emacs bigot, I had my vi brain on. Imagine that! I even
surprised myself.
So... I went to the CD and looked it up. I had the right
concept (last line), but the wrong syntax ($); the right
syntax is, surprisingly, eof().
Here's the code that should work (Oh, not that trick
Bullwinkle, it never works... But this time for sure...).
perl -n -e '$body .= $_ if /^$/ .. eof();' \
-e '$head .= $_ if (1 .. /^$/);' \
-e 'END{print $head, "\n", "="x40, "\n", $body;}'
BTW -- Matt's code would work for 1 file as input, but since
the body flip-flop latches on, it will miss the EOF
condition as subsequent files are processed. If this code
was meant to process multiple files (via <>), the eof() test
is better, but would necessitate a "close ARGV if eof()" to
allow resetting $.. Other problems with this snippet that
prevent it from looping over multiple files, so it's a good
example.
And a quote from the Camel book, via the O'Reilly CD
bookshelf.
Camel CD> In a scalar context, .. returns a Boolean value. The
Camel CD> operator is bi-stable, like an electronic flip-flop, and
Camel CD> emulates the line-range (comma) operator of sed, awk, and
Camel CD> various editors. Each scalar .. operator maintains its own
Camel CD> Boolean state. It is false as long as its left operand is
Camel CD> false. Once the left operand is true, the range operator
Camel CD> stays true until the right operand is true, after which the
Camel CD> range operator becomes false again. (The operator doesn't
Camel CD> become false until the next time it is evaluated. It can
Camel CD> test the right operand and become false on the same
Camel CD> evaluation as the one where it became true (the way awk's
Camel CD> range operator behaves), but it still returns true once. If
Camel CD> you don't want it to test the right operand until the next
Camel CD> evaluation (which is how sed's range operator works), just
Camel CD> use three dots (...) instead of two.) The right operand is
Camel CD> not evaluated while the operator is in the false state, and
Camel CD> the left operand is not evaluated while the operator is in
Camel CD> the true state.
Camel CD>
Camel CD> The precedence is a little lower than || and &&. The value
Camel CD> returned is either the null string for false, or a sequence
Camel CD> number (beginning with 1) for true. The sequence number is
Camel CD> reset for each range encountered. The final sequence number
Camel CD> in a range has the string "E0" appended to it, which doesn't
Camel CD> affect its numeric value, but gives you something to search
Camel CD> for if you want to exclude the endpoint. You can exclude the
Camel CD> beginning point by waiting for the sequence number to be
Camel CD> greater than 1. If either operand of scalar .. is a numeric
Camel CD> literal, that operand is evaluated by comparing it to the
Camel CD> $. variable, which contains the current line number for your
Camel CD> input file. Examples:
Camel CD>
Camel CD> As a scalar operator:
Camel CD>
Camel CD> if (101 .. 200) { print; } # print 2nd hundred lines
Camel CD> next line if (1 .. /^$/); # skip header lines
Camel CD> s/^/> / if (/^$/ .. eof()); # quote body
Camel CD>
--
Michael R. Wolf
All mammals learn by playing!
MichaelRunningWolf at att.net
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
POST TO: spug-list at pm.org PROBLEMS: owner-spug-list at pm.org
Subscriptions; Email to majordomo at pm.org: ACTION LIST EMAIL
Replace ACTION by subscribe or unsubscribe, EMAIL by your Email-address
For daily traffic, use spug-list for LIST ; for weekly, spug-list-digest
Seattle Perl Users Group (SPUG) Home Page: http://seattleperl.org
More information about the spug-list
mailing list