Flip-flop Operator
You know .. as the range operator:But in scalar context, it becomes something completely different:my @nums = (1 .. 5); # (1, 2, 3, 4, 5)
The flip-flop operator. It remembers state between calls. Perfect for extracting sections from files...
Part 1: THE TRICK
Output:while (<DATA>) { print if m~START~ .. m~END~; } __DATA__ ignore this START grab this and this END ignore this too
The flip-flop "turns on" at START and "turns off" at END. Everything between gets printed.START grab this and this END
Part 2: HOW IT WORKS
The .. operator has two states:When the left side matches, it flips ON. When the right side matches, it flips OFF.OFF: Returns false, waiting for left condition to be true ON: Returns true, waiting for right condition to be true
It has MEMORY. Each call remembers the previous state.
.--. |o_o | |:_/ | // \ \ (| | ) /'\_ _/`\ \___)=(___/
Part 3: THE STATES IN DETAIL
Key insight: both the START and END lines are printed. The flip happens AFTER the match.LINE LEFT RIGHT STATE OUTPUT -------------------------------------------------------- ignore false - OFF (skip) START TRUE false ON-> print (just turned on) grab false false ON print (still on) and this false false ON print (still on) END false TRUE ->OFF print (turning off now) ignore false - OFF (skip)
Part 4: LOG FILE PARSING
Extract a specific time range from logs:Grabs everything from 10:00 to 11:00.while (<$log>) { print if m~\[10:00:~ .. m~\[11:00:~; }
Extract a specific request:
Perfect for debugging specific transactions.while (<$log>) { print if m~BEGIN Request #1234~ .. m~END Request #1234~; }
Part 5: LINE NUMBER RANGES
Flip-flop works with line numbers too:Prints lines 3 through 7.while (<DATA>) { print if 3 .. 7; }
How? In scalar context, bare numbers compare against $. (the line number). So 3 .. 7 means "line 3 through line 7."
One-liner: print lines 5-10.perl -ne 'print if 5 .. 10' file.txt
Part 6: THE THREE-DOT VERSION
There's also ...:Difference: with ..., the right side isn't checked on the same line that triggered the left side.while (<DATA>) { print if m~START~ ... m~END~; }
Usually doesn't matter. But for edge cases:.. Two dots: left and right can match on same line ... Three dots: left and right can't match on same line
# Line says "START something END" m~START~ .. m~END~ # Flips on AND off on same line m~START~ ... m~END~ # Flips on, stays on until NEXT END
Part 7: MULTIPLE RANGES
The flip-flop resets when it turns off, so you can catch multiple ranges:Output:while (<DATA>) { print if m~BEGIN~ .. m~END~; } __DATA__ noise BEGIN first block END more noise BEGIN second block END final noise
Both blocks are captured.BEGIN first block END BEGIN second block END
Part 8: CONFIG FILE PARSING
Extract a section from a config:From [database] until the next [section].while (<$config>) { print if m~\[database\]~ .. m~^\[~; }
Gotcha: this also prints the next section header. To exclude it:
Or process into a hash:while (<$config>) { if (m~\[database\]~ .. m~^\[~) { print unless m~^\[~ and not m~\[database\]~; } }
my %config; my $section; while (<$config>) { $section = $1 if m~^\[(\w+)\]~; $config{$section}{$1} = $2 if m~^(\w+)=(.*)~; }
Part 9: ONE-LINERS
Print between patterns:Print lines 10-20:perl -ne 'print if /START/ .. /END/' file.txt
Print from pattern to end of file:perl -ne 'print if 10 .. 20' file.txt
Print from start to pattern:perl -ne 'print if /START/ .. eof' file.txt
perl -ne 'print if 1 .. /END/' file.txt
Part 10: STATEFUL WARNING
The flip-flop has PERSISTENT state. This can bite you:If file1.txt ends without hitting END, the flip-flop stays ON for file2.txt.sub extract_section { my $file = shift; open my $fh, '<', $file or die; while (<$fh>) { print if m~START~ .. m~END~; } } extract_section('file1.txt'); extract_section('file2.txt'); # STATE CARRIES OVER!
Fix: reset state by reaching END, or use a different approach.
Part 11: THE NAME
Flip-flop comes from electronics. A flip-flop circuit has two stable states and switches between them based on input signals.Perl's .. does the same thing: flips on with one condition, flops off with another.ON ----+ +---- ON | | v v [TRIGGER] ^ ^ | | OFF ----+ +---- OFF
Part 12: PRACTICAL EXAMPLE
Extract all function definitions from Perl code:From "sub name" to the closing brace.while (<$source>) { print if m~^sub \w+~ .. m~^}~; }
Extract error blocks from logs:
From ERROR to the next blank line (assuming stack traces are followed by blank lines).while (<$log>) { print if m~ERROR~ .. m~^$~; }
.. / \ ON OFF \ / \/ [MEMORY] Stateful range matching since Perl 1
Created By: Wildcard Wizard. Copyright 2026