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

I don't see why we would need to use Switch to do some case conditionals and was wondering if anyone could shed some light why we have this feature.

To me, the following two codes are identical and are both as simple to make. It does the EXACT same thing and the syntax isn't so different, so why would we use switch instead of elsif?

switch ($wday) { case 0 { print "today is Sun"; } case 1 { print "today is Mon"; } case 2 { print "today is Tue"; } case 3 { print "today is Wed"; } case 4 { print "today is Thu"; } case 5 { print "today is Fri"; } case 6 { print "today is Sat"; } } if ($wday eq "0") { print "today is Sun"; } elsif($wday eq "1") { print "today is Mon"; } elsif($wday eq "2") { print "today is Tue"; } elsif($wday eq "3") { print "today is Wed"; } elsif($wday eq "4") { print "today is Thu"; } elsif($wday eq "5") { print "today is Fri"; } elsif($wday eq "6") { print "today is Sat"; }

Replies are listed 'Best First'.
Re: using Switch;
by Forsaken (Friar) on May 12, 2005 at 06:22 UTC
    This specific example isn't very good in my opinion since there is only possible matching case per result. However, imagine a situation where you have, say, the numbers 1 till 100, and out of those numbers ie 6, 12, 13, 37, 44, 68 and 99 all need to result in performing some sort of action. Now in a situation like that a switch statement would look something like:
    switch($number) { case 6, 12, 13, 37, 44, 68 { \&subroutine(@args); } case 1, 29, 77, 98 { \&othersub(@args); } default { sleep(1); } }
    whereas if you needed to use if-elsif-else it'd be something like:
    if(($number == 6) || ($number == 12) || ($number == 13) || ($number == + 37) || ($number == 44) || ($number == 68)) { \&subroutine(@args) } elsif(($number == 1) || ($number == 29) || ($number == 77) || ($number + == 98)) { \&othersub(@args); } else { sleep(1); }
    In this example I actually resorted to copy-pasting $number, having to copy-paste a piece of code over and over again is in itself a sign that what you're doing is inefficient.

    Now, the method i personally use atm is to create a hash(or in this example above I'd even have used an array because all the case values are numerical) that would look something like this(copied from actual code I use atm):

    my %actions = ( '001' => \&_rpl_welcome, '005' => \&_rpl_isupport, '332' => \&_rpl_topic, '333' => \&_rpl_topicdetails, '352' => \&_rpl_whoreply, '353' => \&_rpl_namreply, 'JOIN' => \&_msg_join, 'PART' => \&_msg_part, 'KICK' => \&_msg_part, 'MODE' => \&_msg_mode, 'QUIT' => \&_msg_quit, ); sub process { my($self, $line) = @_; my @text = split(/\s/, $line); if($actions{$text[1]}) { return(&{$actions{$text[1]}}($self, $line, @text)); } }
    Long story short, the main argument in favor of a switch-like statement is not having to type $wday for each and every comparison. Repetition = bad :-)

    Remember rule one...

Re: using Switch;
by rnahi (Curate) on May 12, 2005 at 05:56 UTC

    why would we use switch instead of elsif?

    I wouldn't.

    And here's why: from the docs:

    BUGS
    There are undoubtedly serious bugs lurking somewhere in code this funky :-) Bug reports and other feedback are most welcome.

    LIMITATIONS
    Due to the heuristic nature of Switch.pm's source parsing, the presence of regexes specified with raw ?...? delimiters may cause mysterious errors. The workaround is to use m?...? instead.
    Due to the way source filters work in Perl, you can't use Switch inside an string eval.
    If your source file is longer then 1 million characters and you have a switch statement that crosses the 1 million (or 2 million, etc.) character boundary you will get mysterious errors. The workaround is to use smaller source files.

    See also Re^4: How to use select (Switch.pm considered harmfull)

Re: using Switch;
by tlm (Prior) on May 12, 2005 at 05:58 UTC

    Now, now. We all have our little obsessions. What would life be like without them?

    On a more serious vein (only slightly), switch statements, at least in some languages, have specialized behaviors (such as fall-through) that are not as easily replicated with a chain of if-statements. Also, a proper switch statement can make the code look a bit cleaner than the if-statement rendition of the same logic. Also, I imagine that compilers may be able to optimize a switch statement more easily than a chain of if-statements, but here I am definitely talking out of my hat.

    I think ultimately it's largely a matter of preference. I haven't used a switch-like statement in years.

    the lowliest monk

Re: using Switch;
by CountZero (Bishop) on May 12, 2005 at 05:42 UTC
    Less typing?

    Why do we have unless when if not works as well? Why do we have for and foreach as they are exactly the same?

    There is more than one way to do it!

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law