SPUG: flip-flops

Yitzchak Scott-Thoennes sthoenna at efn.org
Wed Feb 6 18:36:51 CST 2002

In article <20020206162754.N1565 at hobart.helvella.org>,
Colin Meyer <cmeyer at helvella.org> wrote:
>You can test the state of scalar .. .  That's what you typically do
>with it.
>  if ($bar .. $baz) {
>    print "flip-flop's state is true.\n";
>    print "Next evaluation will check the right hand term.\n";
>  }
>  else {
>    print "flip-flop's state is false.\n";
>    print "Next evaluation will check the left hand term.\n";

>  }

That works with ... but not ..;  I think you need to say
  if (($bar .. $baz) =~ /^\d+$/) {
to find out what the state is at the time of the print.

>Or you could save that state into a variable, as you did in your
>example.  You could have said:
>  print 'The current flip-flop state is: ", $foo?'true':'false', "\n";

Same here.
print 'The current flip-flop state is: ", $foo&&$foo!~/E/?'true':'false', "\n";

Still, your point is valid.  The state is *not* hidden (as it is with the
deprecated m??).  It is returned every time you call the operator.

The point about the doc being difficult to read is valid too.  Can
anyone suggest alternate text?  Perhaps perl code equivalents for ..
and ... if not too lengthy?

Here is how it is now:
In scalar context, ".." returns a boolean value.  The operator is
bistable, like a flip-flop, and emulates the line-range (comma) operator
of B<sed>, B<awk>, and various editors.  Each ".." operator maintains its
own boolean state.  It is false as long as its left operand is false.
Once the left operand is true, the range operator stays true until the
right operand is true, I<AFTER> which the range operator becomes false
again.  It doesn't become false till the next time the range operator is
evaluated.  It can test the right operand and become false on the same
evaluation it became true (as in B<awk>), but it still returns true once.
If you don't want it to test the right operand till the next
evaluation, as in B<sed>, just use three dots ("...") instead of
two.  In all other regards, "..." behaves just like ".." does.

The right operand is not evaluated while the operator is in the
"false" state, and the left operand is not evaluated while the
operator is in the "true" state.  The precedence is a little lower
than || and &&.  The value returned is either the empty string for
false, or a sequence number (beginning with 1) for true.  The
sequence number is reset for each range encountered.  The final
sequence number in a range has the string "E0" appended to it, which
doesn't affect its numeric value, but gives you something to search
for if you want to exclude the endpoint.  You can exclude the
beginning point by waiting for the sequence number to be greater
than 1.  If either operand of scalar ".." is a constant expression,
that operand is implicitly compared to the C<$.> variable, the
current line number.  Examples:

As a scalar operator:

    if (101 .. 200) { print; }  # print 2nd hundred lines
    next line if (1 .. /^$/);   # skip header lines
    s/^/> / if (/^$/ .. eof()); # quote body

    # parse mail messages
    while (<>) {
        $in_header =   1  .. /^$/;
        $in_body   = /^$/ .. eof();
        # do something based on those
    } continue {
        close ARGV if eof;              # reset $. each file


 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     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