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

Hello good Monks,
I'm trying to pass the name of a function as parameter, and thought the below would work:
perl -e '$choice='1'; %hash=( '0' => &one, '1' => &two ); ${\$hash{$ch +oice}}; sub one {print "one"}; sub two {print "two"}'
On execution, it prints "onetwo" while I expected it to run only $hash{1}? What am i doing wrong?

Replies are listed 'Best First'.
Re: execute function with name passed as string parameter
by Utilitarian (Vicar) on May 05, 2011 at 10:09 UTC
    You are not assigning a code_ref in your hash, but rather the out put of your routines, this causes them to run on assignment.
    perl -e '$choice="1"; %hash=( 0 => one, 1 => two ); sub one {print "on +e\n"}; sub two {print "two\n"} &{$hash{$choice}}' two
    print "Good ",qw(night morning afternoon evening)[(localtime)[2]/6]," fellow monks."
Re: execute function with name passed as string parameter
by shmem (Chancellor) on May 05, 2011 at 12:05 UTC

    What the other monks said, but TIMTOWTDI. You can also store subroutine references in your hash and execute them.

    perl -le '$choice='1'; %hash=( '0' => \&one, '1' => \&two ); $hash{$ch +oice}->(); sub one {print "one"}; sub two {print "two"}'

    You could also call the subroutine reference via &{$hash{choice}} - but be aware that there's a subtle difference:

    $\="\n"; # output record separator $choice='1'; %hash=( '0' => \&one, '1' => \&two ); @_ = "fish"; $hash{$choice}->(); &{$hash{$choice}}; one; &one; sub one { print "one", @_ } sub two { print "two", @_ } __END__ two twofish one onefish

    That is, &sub, &$sub, &{gimme_a_subref()} and so on - without parens - pass the current @_ to the called subroutine. Of course, &{$hash{$choice}}() - with parens - passes an empty list.

      OK, so it was a syntax misunderstanding, thank you all.
Re: execute function with name passed as string parameter
by chakreey (Acolyte) on May 05, 2011 at 10:45 UTC
    & symbol in &one, &two is meant for calling subroutines. If your intention is not to call subroutines, but just assign subroutine names, then, use 'one', 'two' For calling subroutine, use &{$hash{$choice}}

    perl -e '$choice='1'; %hash=( '0' => 'one', '1' => 'two');&{$hash{$choice}}; sub one {print "one"};sub two {print "two"}'

Re: execute function with name passed as string parameter
by NetWallah (Canon) on May 06, 2011 at 05:02 UTC
    Simpler calling convention for using a variable as a sub-name - use parens:
    perl -e '$choice="1"; %hash=( 0 => one, 1 => two ); sub one {print "on +e\n"}; sub two {print "two\n"};$hash{1}()'
    prints : "two"

         Syntactic sugar causes cancer of the semicolon.        --Alan Perlis