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

i have some functions: sub post {... etc..
i have a variable: $action = "post";
how do you call the function defined in the variable?
its not &$action;.. i know that much..
i haven't programmed in so long.. probably a dumb question.. thanks for any help though

Replies are listed 'Best First'.
Re: variable function thingy
by Ovid (Cardinal) on Oct 18, 2002 at 02:52 UTC

    If you have your action in a variable, I assume that you have more than one action. If so, set up a dispatch table.

    my %function = ( post => \&post, read => \&read, default => \&default ); my $action = get_action(); $action = 'default' unless ( exists $function{$action} ); $function{$action}->( @arg_list );

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: Function Dereferencing
by tadman (Prior) on Oct 18, 2002 at 06:48 UTC
    Like Ovid, but with a twist:
    # Define a list of 'actions' by listing function names my %function = map { $_ => \&$_ } qw[ post read default ]; # ... my $action = something(); # Wherever you get it $function{$action}->(@somestuff); # Pass any parameters
    You'll want to check that $function{$action} is defined before using it, of course.

    This code works with both strict and warnings engaged.
Re: variable function thingy
by sch (Pilgrim) on Oct 18, 2002 at 02:31 UTC

    What you're looking for is a reference to a sub. You need something like this:

    $func_ref = \&post; #this lets func_ref point at a sub call post ... &$func_ref(); #call the sub we've pointed at

      This answer is correct, but I would also add that it is possible to store the subroutine name rather than as code reference. For example:

      sub test { print "Hello world!\n"; } my $subroutine = "test"; &{$subroutine};

      The caveat to this approach is that it breaks strict refs unless the $subroutine scalar is evaluated (eg. eval $subroutine).

       

      Update - Check out the nifty example from broquaint in this thread here

       

      perl -e 'print+unpack("N",pack("B32","00000000000000000000000111010010")),"\n"'

Re: variable function thingy
by Aristotle (Chancellor) on Oct 18, 2002 at 14:17 UTC

    Btw, if the $action variable comes from user input - most likely in a CGI script -, you will want to check that it actually contains the name of a function you have intended for public calling. That's easiest to make sure if you use a hash to map names to coderefs.

    Alternatively, you could put the public functions in a package and use the symbol table hash to get at them.

    if(exists $Action::{$action}) { $Action::{$action}->(@params); } else { croak "No such action '$action'"; } package Action; sub post { # ... }

    Makeshifts last the longest.

Re: variable function thingy
by Anonymous Monk on Oct 18, 2002 at 04:49 UTC
    $var="post"; eval "&$var";
      Works with strict and doesn't require an eval()
      sub foo { print "in foo()\n"; } my $func_name = "foo"; &{\&{$func_name}}(); __output__ in foo()

      HTH

      _________
      broquaint

        Cute. Is this a Perl bug?

        Either way a simple no strict 'refs'; seems like the way to go.

        sub foo { print "in foo\n"; } { no strict 'refs'; &{"foo"}; }
A reply falls below the community's threshold of quality. You may see it by logging in.