perlmeditation
mr_mischief
In [doc://perlsyn] you can find the words 'You can use the "continue" keyword to fall through from one case to the next'. You can also find this example:
<c>
given($foo) {
when (/x/) { say '$foo contains an x'; continue }
when (/y/) { say '$foo contains a y' }
default { say '$foo contains neither an x nor a y' }
}
</c>
Now, I'm not primarily a C programmer, but what I took "fall through" to mean is not what happens there. The "continue" doesn't skip the implicit break in the case, but means to actually continue testing cases.
<p>
<readmore>
That means this Perl code:
<c>#!/usr/local/bin/perl
use feature qw{ switch };
use strict;
use warnings;
sub match {
my $i = 0;
my $foo = shift;
given ( $foo ) {
when ( 1 ) { $i++; continue; }
when ( 2 ) { $i++; continue; }
when ( 3 ) { $i++; continue; }
when ( 4 ) { $i++; }
}
print "$foo: ";
print "4!" if 4 == $i;
print "\n";
}
match 1;
match 2;
match 3;
match 4;
match 5;
</c>
which prints:
<c>
1:
2:
3:
4:
5:
</c>
is not equivalent to this C code:
<c>
#include <stdio.h>
#include <stdlib.h>
int match ( int foo ) {
int i = 0;
printf( "%d: ", foo );
switch ( foo ) {
case 1: i++;
case 2: i++;
case 3: i++;
case 4: i++;
break;
}
if ( 4 == i ) {
printf( "4" );
}
printf( "\n" );
}
int main ( int argc, const char **argv ) {
match( 1 );
match( 2 );
match( 3 );
match( 4 );
match( 5 );
exit( 0 );
}
</c>
which prints:
<c>
1: 4
2:
3:
4:
5:
</c>
</readmore>
<p>
However, it means you can do neat tricks like this:
<c>#!/usr/local/bin/perl
use feature qw{ switch };
use strict;
use warnings;
sub match {
my $i = 0;
my $foo = shift;
print $foo . ': ';
given ( $foo ) {
when ( /^Just / ) { $i++; continue; }
when ( /another / ) { $i++; continue; }
when ( /[Pp]erl / ) { $i++; continue; }
when ( /hacker\.?$/ ) { $i++; }
}
print 'Me too!' if 4 == $i;
print "\n";
}
match 'Just another Perl hacker';
match 'Just another Perl slacker';
</c>
which prints:
<c>
Just another Perl hacker: Me too!
Just another Perl slacker:
</c>
So don't forget that you'll have to give up a little bit of convenience you might be used to with straight fall through. Happily, though, you end up with a good deal more convenience by being able to restart the switch and having the smart match applied again to the remaining cases.
<p>
Unfortunately, this feature of continuing through the tests and having a default in the same switch statement are not really that smart a combination. Try giving that example from [doc://perlsyn] the value <c>x</c> for <c>$foo</c>, and you get:
<c>
$foo contains an x
$foo contains neither an x nor a y
</c>
... which makes very little sense.