SPUG: flip..flops
Michael R. Wolf
MichaelRWolf at att.net
Thu Apr 22 09:31:46 CDT 2004
FYI..
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.
Enjoy,
Michael
[...]
> 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