SPUG: flip..flops

Michael R. Wolf MichaelRWolf at att.net
Thu Apr 22 09:31:46 CDT 2004


Here's the guts of the message I sent to my colleague regarding
double-dots (range and flip-flop), in the hopes that it shines a light
into a dark, oft-overlooked, powerful corner of Perl.



> I thought of you recently too.  I saw something in Ellie Quigley's
> Perl book that amazed me about Perl:
> open(DB, "emp.names") || die "Can't open emp.names: $!";
> while (<DB>) {
>    print if /Norma/ .. eof();
> }
> It's the use of the range operator in that way.  It blew my mind.

Actually, dot-dot is overloaded, and in this case is not the range
operator, it's the flip-flop operator.  In an array context, it's a
range operator.

  @toddler = (1..3);
  @teenager = (13..19);

But in a scalar context, it's a flip-flop binary operator. The
operator evaluates as false until the LHS being true triggers it to
flip to a true state, which it stays in until the RHS being true
triggers it to flip back to false. There's a 2-dot version and a 3-dot
version, the difference being whether both sides can get evaluated for
the same line and trigger on/off for the same line or whether they
must do it on separate lines.

Her example shows printing lines from a file starting at lines that
contain norma Norma until the end of file. Another classic example is
parsing an email message. The header is the first line through a blank
line; the body is the rest.

while (<>) {
    if (1 .. /^\s*$/) {
	push @header, $_;
    } else {
	push @body, $_;

Or, more perlishly (probably *too* perlishly):

    1 .. /^\s*$/ ? push @header, $_ : push @body, $_ while (<>);

Is this a better style...?

    1 .. /^\s*$/           ? 
        push @header, $_   : 
        push @body, $_ 
    while (<>);

Or this....??

    while (<>) {
        1 .. /^\s*$/           ? 
            push @header, $_   : 
            push @body, $_

The last 3 all compile and run the same.

Perl... I really appreciate its flexability and expressiveness.

Michael R. Wolf
    All mammals learn by playing!
        MichaelRWolf at att.net

More information about the spug-list mailing list