Have you ever wondered where fashion and software development overlap? If so, look no further than the flip-flop. It's a feature available in Sed, Awk, Ruby and Perl which - akin to its namesake - is short, revealing and can raise a few eyebrows

Robot Gear flip-flops by Cafepress



You're probably familiar with the range operator '..' where this statement You're probably familiar with the range operator '..' where this statement





my @foo = (3..10);





creates an array @foo containing (3, 4, 5, 6, 7, 8, 9, 10) . But if instead you accidentally write:





my $foo = (3..10);





you'll stumble on this error message:





Use of uninitialized value $. in range (or flip) at...





Do you wonder why the compiler worries that you're going to flip? Think again. It means you've used the flip-flop operator.





What's the flip-flop operator you ask? As a symbol, the flip-flop is the same as the range operator, but when used in scalar context it's a 'boolean' along the lines of 'Am I caught between these truths?'.





It's much easier to show by example. Consider this "flip-free" code where you want to print everything enclosed in 'f' and 'zle'.





my @array = qw/frizzle this fit sizzle bit/; my $switch = 0; foreach my $word (@array) { if ($switch) { say $word; # switch off if we see the end delimiter $switch = $word !~ m/zle/; } else { $switch = $word =~ m/f/; if ($switch) { say $word ; $switch = $word !~ m/zle/; } } }





it has the output





frizzle fit sizzle



Here's the equivalent code using the flip-flop operator:





foreach (@array) { say if (/f/../zle/); }



or to be more explicit:





foreach my $word (@array) { say $word if ($word =~ m/f/ .. $word =~ m/zle/); }



Reading the "flip-free" code above, you'll see that there were three places where the switch was changed - "frizzle" (on and off), "fit" (on) and "sizzle" (off).

Now what if you decide that you don't want the switch flicked twice in the same match. Instead, you want the output

frizzle this fit sizzle

Easy - just change the two-dot flip flop to the three-dot flip-flop: my @array = qw/frizzle this fit sizzle bit/; foreach (@array) { say if (/f/ ... /zle/); }

Or fliplessly:

my @array = qw/frizzle this fit sizzle bit/; my $switch = 0; foreach my $word (@array) { if ($switch) { say $word; $switch = $word !~ m/zle/; } else { $switch = $word =~ m/f/; say $word if $switch; } }