perlswitch-statement

Obtain a switch/case behaviour in Perl 5


Is there a neat way of making a case or switch statement in Perl 5?. It seems to me they should include a switch on version 6.

I need this control structure in a script, and I've heard you can import a "switch module". But how can I achieve it without imports to minimize dependencies and acquire portability?


Solution

  • If you are using Perl 5.10 you have given/when which is a switch statement (note, it can do more than compare with regexes, read the linked docs to see its full potential):

    #or any of the dozen other ways to tell 5.10 to use its new features
    use feature qw/switch/; 
    
    given($string) {
        when (/^abc/) { $abc     = 1; }
        when (/^def/) { $def     = 1; }
        when (/^xyz/) { $xyz     = 1; }
        default       { $nothing = 1; }
    }
    

    If you are using Perl 5.8 or earlier you must make do with if/elsif/else statements:

    if    ($string =~ /^abc/) { $abc     = 1; }
    elsif ($string =~ /^def/) { $def     = 1; }
    elsif ($string =~ /^zyz/) { $xyz     = 1; }
    else                      { $nothing = 1; }
    

    or nested condition operators (?:):

    $string =~ /^abc/ ? $abc     = 1  :
    $string =~ /^def/ ? $def     = 1  :
    $string =~ /^xyz/ ? $xyz     = 1  :
                        $nothing = 1;
    

    There is a module in Core Perl (Switch) that gives you fake switch statements via source filters, but it is my understanding that it is fragile:

    use Switch;
    
    switch ($string) {
        case /^abc/ {
        case /^abc/ { $abc     = 1 }
        case /^def/ { $def     = 1 }
        case /^xyz/ { $xyz     = 1 } 
        else        { $nothing = 1 }
    }
    

    or the alternate syntax

    use Switch 'Perl6';
    
    given ($string) {  
        when /^abc/ { $abc     = 1; }
        when /^def/ { $def     = 1; }
        when /^xyz/ { $xyz     = 1; }
        default     { $nothing = 1; }
    }