http://qs321.pair.com?node_id=1164447

Hello everyone,

A recent thread reminded me of a script I wrote years ago while learning about the flip-flop operator (aka the range operator in scalar context), and I thought I'd share it in case it helps someone else.

The script, which I've included below the output, runs through a sequence of true/false values, tests whether the right-hand-side and/or left-hand-side of the operator is evaluated (marked by an asterisk in the table), gets the return value of the operator, and outputs all that in the following handy table. I hope it illustrates the difference between the .. (two-dot) and ... (three-dot) versions of the operator: two dots will immediately evaluate the RHS if the LHS is true, three dots will wait until the next evaluation.

```*** Demonstration of the Flip-Flop Operators ***

__A______B____X___   __A______B____X___
0* ..  0  =          0* ... 0  =
0* ..  1  =          0* ... 1  =
0* ..  0  =          0* ... 0  =
1* ..  0* = 1        1* ... 0  = 1
0  ..  0* = 2        0  ... 0* = 2
0  ..  0* = 3        0  ... 0* = 3
0  ..  1* = 4E0      0  ... 1* = 4E0
0* ..  0  =          0* ... 0  =
0* ..  0  =          0* ... 0  =
1* ..  1* = 1E0      1* ... 1  = 1
0* ..  0  =          0  ... 0* = 2
0* ..  0  =          0  ... 0* = 3
1* ..  0* = 1        1  ... 0* = 4
0  ..  0* = 2        0  ... 0* = 5
0  ..  1* = 3E0      0  ... 1* = 6E0
0* ..  1  =          0* ... 1  =
1* ..  1* = 1E0      1* ... 1  = 1
1* ..  0* = 1        1  ... 0* = 2
0  ..  0* = 2        0  ... 0* = 3
0  ..  1* = 3E0      0  ... 1* = 4E0
0* ..  0  =          0* ... 0  =
1* ..  1* = 1E0      1* ... 1  = 1
1* ..  1* = 1E0      1  ... 1* = 2E0
1* ..  1* = 1E0      1* ... 1  = 1
0* ..  0  =          0  ... 0* = 2
0* ..  1  =          0  ... 1* = 3E0
0* ..  0  =          0* ... 0  =

(* = Evaluated)
```#!/usr/bin/env perl
use warnings;
use strict;

print "*** Demonstration of the Flip-Flop Operators ***\n\n";

my @tests = qw/
0:0 0:1 0:0 1:0 0:0 0:0 0:1 0:0 0:0
1:1 0:0 0:0 1:0 0:0 0:1 0:1 1:1 1:0
0:0 0:1 0:0 1:1 1:1 1:1 0:0 0:1 0:0 /;

print join('   ', ("__A______B____X___") x 2), "\n";
sub fmt {
my (\$lv,\$le,\$op,\$rv,\$re,\$v) = @_;
return sprintf '  %s%s %-3s %s%s = %-3s ',
\$lv, \$le?'*':' ', \$op,
\$rv, \$re?'*':' ', \$v;
}

for (@tests) {
my (\$lv, \$rv) = split /:/;

my (\$le, \$re);
my \$lf = sub { \$le=1; \$lv };
my \$rf = sub { \$re=1; \$rv };

(\$le, \$re) = (0,0);
my \$v1 = &\$lf ..  &\$rf;
print fmt(\$lv,\$le,'..' ,\$rv,\$re,\$v1);

print '   ';

(\$le, \$re) = (0,0);
my \$v2 = &\$lf ... &\$rf;
print fmt(\$lv,\$le,'...',\$rv,\$re,\$v2);

print "\n";
}

print "\n(* = Evaluated)\n";