开发者

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";}
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜