Perl switch not falling through properly?
I have a value ($field) that I want to test. Read the perl doc (http://perldoc.perl.org/Switch.html#Allowing-fall-through), and figured that I had this nailed. Seems not, because if I pass 'Exposure Bias', there is no output, though 'Exposure Bias Value' works as it should. It throws no errors, so I have no clue.
use Switch;
use strict; use warnings;
my $field = 'Exposure Bias';
switch($field){
开发者_高级运维case 'Exposure Bias' {next;}
case 'Exposure Bias Value' {print "Exp: $field\n";}
}
Update
I'm assuming the wrong thing it seems. What I want to do with this switch is have the print run if either case is matched. I thought that next would pass control on to the next case's code, but that was my mistake.
How do I code this so that the code in the second case runs if the first case is matched?
Working Solution
given($field){
when(['Exposure Bias','Exposure Bias Value']){print "Exp: $field\n";}
}
DVK's comments about why your switch isn't working as you expect are correct, but he neglects to mention a better, safer way to implement your switch.
Switch
is built using source filters and has been deprecated and is best avoided. If you are working with Perl 5.10 or newer, use given
and when
to build your switch statement:
use strict;
use warnings;
use feature qw(switch);
my $field = 'Exposure Bias';
given($field) {
when ([
'Exposure Bias',
'Exposure Bias Value',
]) {
print 'Exp: ' . $field . "\n";
}
}
See perlsyn for more info.
The switch value 'Exposure Bias' does not equal the second case's value (both of them being strings, the string equality is used as per the table in the beginning of POD).
Therefore, when the fall-through causes the switch to go to the second case; it simply fails to match. Since there's no more cases, it quits.
To illustrate, this code will print output Second case for bias
if you run it:
use Switch;
use strict; use warnings;
my $field = 'Exposure Bias';
switch($field){
case 'Exposure Bias' {next;}
case 'Exposure Bias Value' {print 'Exp: ' . $field . "\n";}
case /Exposure Bias/ { print "Second case for bias\n";} # RegExp match
}
It starts to work just like your code (first one matches, next
causes fall-through to second one, second one doesn't match) and since there is a third case, and it matches, that one's block gets executed.
I'm not entirely sure how you wanted the second case to match (e.g. under what logic would "Exposure Bias Value" match "Exposure Bias" value) - the only one that comes to mind was that you wanted your "field" to act as a regular expression and each case value to be a string matched against that regular expression. If so, you need to write it as follows, using the fact that a switch value can be a subroutine reference (unfortunately it can't be a regular expression, although the case one can, as you saw above):
use Switch;
use strict; use warnings;
my $field = sub { return $_[0] =~ /Exposure Bias/ };
switch($field){
case 'Exposure Bias' {next;}
case 'Exposure Bias Value' {print "Exp\n";}
}
The latter produces Exp
output.
UPDATE
Based on the updated info in the question, the easiest thing to do is to simply specify both strings in the second case as an arrayref:
use Switch;
use strict; use warnings;
my $field = "Exposure Bias";
switch($field){
case 'Exposure Bias' { print "First match\n"; next;}
case ['Exposure Bias Value', 'Exposure Bias'] {print "Exp: $field\n";}
}
$ perl ~/a.pl
First match
Exp: Exposure Bias
Better to abstract away the value, of course:
use Switch;
use strict; use warnings;
my $field = "Exposure Bias";
my $exp_bias = 'Exposure Bias';
switch($field){
case "$exp_bias" { print "First match\n"; next;}
case ['Exposure Bias Value', "$exp_bias" ] {print "Exp: $field\n";}
}
精彩评论