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.
| [reply] [Watch: Dir/Any] [d/l] [select] |
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.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
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
| [reply] [Watch: Dir/Any] |
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)
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: Perl/Unix case
by Anonymous Monk on Oct 22, 2004 at 15:41 UTC
|
perldoc -q 'case statement'
| [reply] [Watch: Dir/Any] [d/l] |
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. | [reply] [Watch: Dir/Any] [d/l] |
Re: Perl/Unix case
by Joost (Canon) on Oct 22, 2004 at 16:38 UTC
|
In addition to the other suggestions, you could try Switch
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] |