Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
PerlMonks or possible alternatives

by smack (Beadle)
on May 20, 2005 at 12:40 UTC ( #458948=perlquestion: print w/replies, xml ) Need Help??

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

Greetings Fellow Monks,

I have recently found myself with an out of control "if" statement. It started out innocently enough; with 3 conditions. It has grown, however, to 10 conditions (and is going to keep growing). I have tried to use a switch statement, but Switch.PM breaks my entire program just by including it! All the code does is evaluate a variable, and based on the content call a function. My question is: What should I be using if I cannot use a case statement in such a situation? Is there a better module I can use, or coding technique? I can't help but feel this "if" statement is far too big. =)

Best Regards,


20050521 Edit by broquaint: Changed title from 'Switch.PM'

Replies are listed 'Best First'.
Re: or possible alternatives
by Animator (Hermit) on May 20, 2005 at 12:44 UTC

    If all it does is evaluate a variable, then you might want to use a dispatch table... with a code-ref

    Something like:

    my %dispatch = ( value1 => \&code_A(); value2 => \&code_B(); value3 => \&code_C(); ); # and in your code: if (exists $dispatch{$somevar}) { $dispatch{$somevar}->(); }

Re: or possible alternatives
by Joost (Canon) on May 20, 2005 at 12:48 UTC
    If your conditions are simple enough you can do it easily:
    my $contition = $some_letter; my %dispatch = ( a => sub { # do something with a }, b => \&do_something_with_b, c => ... ); $dispatch{$condition}->();
    You could even put the conditions as code blocks, tough I doubt it would make an improvement over a long if .. elsif ... statement:
    my @dispatch = ( sub { shift() eq 'a' } => sub { "do something with a" }, sub { shift() == 105 } => sub { "do something with 105" }, ); for (my $i; $i < @dispatch; $i+=2) { $dispatch[$i+1]->() if $dispatch[$i]->($variable); }
Re: or possible alternatives
by broquaint (Abbot) on May 21, 2005 at 14:28 UTC
    What marvellous timing as I can point you to my new module, Switch::Perlish (which should be available on CPAN any moment now if it isn't already). So extrapolating from your node this code should do the job:
    use Switch::Perlish; switch $your_var, sub { case 'this', \&this_function; case 'that', \&that_function; case 'the', \&the_function; case 'other', \&other_function; default sub { print "Nothing matched '$your_var'\n" }; };


      broquaint++. Very clever indeed.

      I wish I'd written that :). I have had half a dozen attempts at doing so and got near to something usable a few times, but always got hung up on weird syntax and error handling.

      You could remove the need for the 'sub' keyword on the 'default' with a prototype, but that would be inconsistant with 'case'. Now, if only prototypes allowed the use of & in the positions other than the first to accept a bare-block, this could be damn nearly perfect.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
      Thank you so much for your help. I will definitely be using this module!

Re: or possible alternatives
by lupey (Monk) on May 20, 2005 at 16:35 UTC
    Also, you can check out perldoc perlsyn and look for the section titled Basic BLOCKs and Switch Statements. It gives some examples on how to fake a C-style switch statement.


Re: or possible alternatives
by Anonymous Monk on May 20, 2005 at 12:44 UTC
    What kind of conditions are you testing? Don't use Switch. Stick with if, but use better indenting.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://458948]
Approved by Joost
Front-paged by broquaint
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (2)
As of 2022-09-27 02:27 GMT
Find Nodes?
    Voting Booth?
    I prefer my indexes to start at:

    Results (118 votes). Check out past polls.