Lhamo_rin has asked for the wisdom of the Perl Monks concerning the following question:

Is there a statement in Perl similar to the "switch" statement used in c++?

Title edit by tye

Replies are listed 'Best First'.
Re: Switch
by broquaint (Abbot) on Sep 29, 2003 at 13:52 UTC
    Natively, there's no equivalent statement, however TheDamian has rather fiendishly implemented a perl-ish equivalent called Switch. However, it can be roughly emulated using bare blocks and labels as illustrated in the Basic BLOCKs and Switch Statements section of perlsyn.

    HTH

    _________
    broquaint

Re: Switch
by CombatSquirrel (Hermit) on Sep 29, 2003 at 13:53 UTC
    Enter perldoc -q switch.
    Output:

    How do I create a switch or case statement?

    This is explained in more depth in the the perlsyn manpage. Briefly, there's no official case statement, because of the variety of tests possible in Perl (numeric comparison, string comparison, glob comparison, regex matching, overloaded comparisons, ...). Larry couldn't decide how best to do this, so he left it out, even though it's been on the wish list since perl1.

    The general answer is to write a construct like this:

    for ($variable_to_test) { if (/pat1/) { } # do something elsif (/pat2/) { } # do something else elsif (/pat3/) { } # do something else else { } # default }
    Here's a simple example of a switch based on pattern matching, this time lined up in a way to make it look more like a switch statement. We'll do a multi-way conditional based on the type of reference stored in $whatchamacallit:
    SWITCH: for (ref $whatchamacallit) { /^$/ && die "not a reference"; /SCALAR/ && do { print_scalar($$ref); last SWITCH; }; /ARRAY/ && do { print_array(@$ref); last SWITCH; }; /HASH/ && do { print_hash(%$ref); last SWITCH; }; /CODE/ && do { warn "can't print function ref"; last SWITCH; }; # DEFAULT warn "User defined type skipped"; }
    See "perlsyn/"Basic BLOCKs and Switch Statements"" for many other examples in this style.

    Sometimes you should change the positions of the constant and the variable. For example, let's say you wanted to test which of many answers you were given, but in a caseinsensitive way that also allows abbreviations. You can use the following technique if the strings all start with different characters or if you want to arrange the matches so that one takes precedence over another, as ""SEND"" has precedence over ""STOP"" here:

    chomp($answer = <>); if ("SEND" =~ /^\Q$answer/i) { print "Action is send\n" } elsif ("STOP" =~ /^\Q$answer/i) { print "Action is stop\n" } elsif ("ABORT" =~ /^\Q$answer/i) { print "Action is abort\n" } elsif ("LIST" =~ /^\Q$answer/i) { print "Action is list\n" } elsif ("EDIT" =~ /^\Q$answer/i) { print "Action is edit\n" }
    A totally different approach is to create a hash of function references.
    my %commands = ( "happy" => \&joy, "sad", => \&sullen, "done" => sub { die "See ya!" }, "mad" => \&angry, ); print "How are you? "; chomp($string = <STDIN>); if ($commands{$string}) { $commands{$string}->(); } else { print "No such command: $string\n"; }

    Hope this helped.
    CombatSquirrel.
    Entropy is the tendency of everything going to hell.
Re: Switch
by hardburn (Abbot) on Sep 29, 2003 at 14:40 UTC

    You'll note that the methods noted in above post, while supporting the general use of switch, do not support default fall-through like C does. To be fair, this is one of the most contreversial features in C (culminating in Duff's Device), but arguments over potential abuse of a feature never stopped Perl before. So it's no small irony that even Java supports a more C-ish switch statment then Perl does.

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    Note: All code is untested, unless otherwise stated

Re: Switch statement in Perl?
by BrowserUk (Patriarch) on Sep 29, 2003 at 16:31 UTC

    You might like to look at the thread at Simple Switch statement for a recent discussion of an interesting variation on the theme of self-implemented switch statements. This, in a slightly modifed as shown at Re: Simple Switch statement, is now my current favorite variation.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
    If I understand your problem, I can solve it! Of course, the same can be said for you.