Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Perl/Unix case

by Ronnie (Scribe)
on Oct 22, 2004 at 15:35 UTC ( [id://401524]=perlquestion: print w/replies, xml ) Need Help??

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

It's novice grovel time again chaps! Is there a Perl equivalent of the UNIX case statement? I've not found one but a colleague has a need for this type of thing. ( I suggested a hash table containing the names of local subroutines but was scoffed at!) She has a Perl script that returns 2 values. Depending on the 4 allowed combinations of these values she performs different actions. A nested if would also do but is rather ugly. In a similar vain I've not found a way to action several commands as the right hand side of an "or" statement.
if ($fred) { &ACC_Oracle_profile or &ACC_LOG_ERROR" ; &ACC_Oracle_DBI("$a","$b") or die "help ma bo +ab!" ; &ACC_end or die "We're doomed!" ; $end_it() ; }
Is there a way to do this (other than by writing a sub or am I being Very silly)? Cheers, Ronnie

Replies are listed 'Best First'.
Re: Perl/Unix case
by davido (Cardinal) on Oct 22, 2004 at 15:41 UTC

    Perl doesn't have a built-in switch construct. But there are many ways to accomplish it. The hashtable you mentioned is one of them. Here's another:

    SWITCH: { ($condition) && do { # stuff; last SWITCH; }; ($condition2) && do { # something else; last SWITCH; }; die "Neither condition was met.\n"; }

    This is discussed in perlsyn, I believe.


    Dave

Re: Perl/Unix case
by gothic_mallard (Pilgrim) on Oct 22, 2004 at 15:41 UTC

    Perl unfortuantly doesn't have a case statement but, as with most things, TMTOW to roll your own.

    The simplest, obviously, is with a set of if...elsif...else statements which does essentially the same thing if looking a little less elegant.

    The hash is another possibility and maybe faster than the if... route (but don't quote me on that), although unless you have lots of options then the difference is probably going to be negligable.

    --- Jay

    All code is untested unless otherwise stated.

      a set of if...elsif...else statements which does essentially the same thing
      It's almost the same. From what I recall of C programming, that language implements switches with jump i.e. it knows where in memory to find the code it needs to execute. This is akin to the hash solution that you mention. I've seen perl core dump on a program with too large a block of if..elsif..elsif... . That was a couple of years ago, but either way, I think that the dispatch table is the better solution for more reasons than just that.

      thor

      Feel the white light, the light within
      Be your own disciple, fan the sparks of will
      For all of us waiting, your kingdom will come

Re: Perl/Unix case
by Elgon (Curate) on Oct 22, 2004 at 17:45 UTC

    Your suggestion was a good one IMHO, or at least very close to being good - look up dispatch tables and/or coderefs in super search and you should find something. They are a useful and elegant way of handling this kind of problem.

    UPDATE: Look here for a small hint on the use of dispatch tables. Code also added below...

    my $foo; my $bar; my @args; # Get $foo $bar and @args somewhere around here... my %despatch_table = ("one" => ( "alpha" => \&func_onealpha, "beta" => \&func_onebeta), "two" => ("alpha" => \&func_twoalpha, "beta" => \&func_twobeta)); my $answer; if ($answer = &${$despatch_table{$foo}}{bar}(@args)) { # Do something with $answer } else { # Bad values throw an error } sub func_onealpha { # Do stuff here } sub func_onebeta { # Do stuff here } sub func_twoalpha { # Do stuff here } sub func_twobeta { # Do stuff here }

    You use the string values of $foo and $bar as keys to the hash, which contains references to subroutines (in this case named, but can be anonymous subs in the hash itself. This is a bit of a rigmarole to go through, but ends up being better to work with than a huge nest of if statements.

    Elgon

    It is better either to be silent, or to say things of more value than silence. Sooner throw a pearl at hazard than an idle or useless word; and do not say a little in many words, but a great deal in a few.

    Pythagoras (582 BC - 507 BC)

Re: Perl/Unix case
by Anonymous Monk on Oct 22, 2004 at 15:41 UTC
Re: Perl/Unix case
by Random_Walk (Prior) on Oct 22, 2004 at 16:26 UTC

    Previous posters have pointed out perlish case/switch hacks so I will not even go there. However if are dependant on the values of multiple variables nested ifs will be more efficient as the value of each var is only tested once..

    if ($a==1) { if ($b==1) {#do a1b1} else {#do a1b2} }else{ if ($b==1) {#do a2b1} else {#do a2b2} }
    See, it is a feature not a limitation :-) but you are right it is not as good looking as a case/switch statement.

    Cheers,
    R.

Re: Perl/Unix case
by Joost (Canon) on Oct 22, 2004 at 16:38 UTC

      Only if you want to track down seemingly unrelated bugs for hours on end due to Switch.pm using a source filter.

      "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://401524]
Approved by jfroebe
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (7)
As of 2024-03-28 09:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found