Re: switch statement for subroutines?
by Masem (Monsignor) on Jul 27, 2001 at 23:15 UTC
|
Use a hash; much easier to read than long if statements, and more extendable:
my %subhash = { do_run => \&do_run,
do_walk => \&do_walk,
do_skip => \&do_skip };
foreach ( @do_something ) {
if ( defined $subhash{ $_ } ) { &{ $subhash{ $_ } }(); }
}
-----------------------------------------------------
Dr. Michael K. Neylon - mneylon-pm@masemware.com
||
"You've left the lens cap of your mind on again, Pinky" - The Brain
| [reply] [d/l] |
|
|
Hello,
I noticed you used the curley brackets instead of the regular brackets in the hash assignment, but that's okay ;)
I guess doing the following should be more readable, no?
foreach ( @do_something ) {
defined $subhash{$_} and $subhash{$_}->()
}
# OR
foreach ( @do_something ) {
$subhash{$_}->() if defined $subhash{$_}
}
This way we avoid most of the ugly punctuation marks.
Aziz
| [reply] [d/l] |
(ar0n: use Switch) Re: switch statement for subroutines?
by ar0n (Priest) on Jul 27, 2001 at 23:05 UTC
|
CPAN is your friend, grasshopper:
use Switch;
foreach my $val (@array) {
switch ($val) {
case "do_walk" {
do_walk()
}
case "do_run" {
do_run();
}
case "do_skip" {
do_skip();
}
}
}
[ ar0n ]
| [reply] [d/l] |
|
|
| [reply] |
Re: switch statement for subroutines?
by dragonchild (Archbishop) on Jul 27, 2001 at 23:13 UTC
|
ar0n is perfectly correct, however there's a neat Perl-ism in your example.
&$_ for @do_something;
This, of course, assumes that all the strings in @do_something have functions associated with them. Otherwise, Perl will die and complain.
However, you can get past that by doing something like:
my $foo = Some::Class->new;
$foo->$_ if $foo->can($_) for @do_something;
*grins* A really neat thing about Perl OO. | [reply] [d/l] [select] |
Re: switch statement for subroutines?
by bikeNomad (Priest) on Jul 27, 2001 at 23:17 UTC
|
{ # localize the lack of B&D
no strict 'refs';
foreach my $sub (@do_something) { $sub->() }
}
| [reply] [d/l] |
Re: switch statement for subroutines?
by HyperZonk (Friar) on Jul 28, 2001 at 04:19 UTC
|
All of the code provided in reply has been workable, but I
notice that no one has mentioned a couple of errors in your
code to you. While good solutions have been given to solve
your current dilemma, I'd like to point the errors out to
you so they don't bite you at a later date.
In your code, you attempt to test with $_ = "do_run".
This is actually assigning 'do_run' to the variable. The
string test operator is eq, so you want if $_ eq 'do_run'.
(For numeric comparison, use ==). Also, you do
not call a subroutine in perl -- just use the
subroutine name.
When 'if' begins the line and is followed by a comparison,
the comparison requires parentheses. Also, the block to be
run on true needs to have brackets. Both of these can be
eliminated in the switched around version (see below) due
to precedence and syntax.
A final note (this isn't a bug, just a style
issue) ... you are using double-quotes, which does variable
interpolation within the string. Since you are not interpolating
variables, single quotes will suffice. So the way a string
comparison might look is:
if ($_ eq 'do_run') { do_run() }
The alternative style ("switched around" as I called it above)
would appear as:
do_run() if $_ eq 'do_run';
-HZ | [reply] [d/l] [select] |
Re: switch statement for subroutines?
by enoch (Chaplain) on Jul 28, 2001 at 01:34 UTC
|
I believe I first saw this in Programming Perl.
SWITCH:
{
do_run() last SWITCH if $_ eq "do_run";
do_walk() last SWITCH if $_ eq "do_walk";
do_skip() last SWITCH if $_ eq "do_skip";
}
Jeremy | [reply] [d/l] |
Re: switch statement for subroutines?
by petral (Curate) on Jul 29, 2001 at 13:28 UTC
|
Since no one's mentioned it, here's one more WTDI:
for (@do_something) {
/do_run/ ? do_run()
: /do_walk/ ? do_walk()
: /do_skip ? do_skip()
: next; # ?!? catch none-of-the-above either error or default
}
  p
| [reply] [d/l] |