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

And a quote from the Camel book, via the O'Reilly CD

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