in reply to How to call subroutines using variables ?

You probably shouldn't do that. It amounts to using symbolic references, which is disallowed by using strict.

It's probably better to use a reference to the subroutine instead of its name:

#!/usr/local/bin/perl use strict; use warnings; my $s = \&res; $s->(); sub res { print "hai"; }

edit: see also perlref

Replies are listed 'Best First'.
Re^2: How to call subroutines using variables ?
by Trizor (Pilgrim) on Mar 22, 2007 at 23:02 UTC
    However AM said that they had a hash of sub names, possibly from a external library. If you cannot convert the hash of subroutine names to a hash of code references  $s{key}=\&valsub; then use a bare BLOCK to turn strict off only when calling subs from that hash:
    { # Get an enclosing lexical scope no strict 'refs'; # allow symbolic refrence shenanigains &$SubHash{key}(); # Call sub } # Back to strict 'refs'
    or write a sub for this purpose (This assumes $SubHash is a global)
    CallFromHash { no strict 'refs'; # allow symbolic refrence shenanigains return &$SubHash{shift(@_)}(@_); #Call the sub in the first arg with + the rest of @_ as args and return }
    However a hash of sub names is probably a bad idea to start with, and you should reconsider your design to use hard refs (mentioned by Joost) or remove the hash all together if possible.
    Update: Forgot Amperstands
Re^2: How to call subroutines using variables ?
by bradcathey (Prior) on Jun 09, 2007 at 17:31 UTC

    I tried:

    my @all_subs = (\&sub_1,\&sub_2); $all_subs[1]->();

    which worked fine. But in CGI::Application I'm using $self->, as in:

    $self->$all_subs[1]->();

    but got a syntax error (doesn't like the 2nd arrow operator). How can I get around this? Thanks.

    Update: fixed some punctuation


    —Brad
    "The important work of moving the world forward does not wait to be done by perfect men." George Eliot

      which worked fine. But in CGI::Application I'm using $self->, as in:

      $self->$all_subs[1]->();

      Use:

      my $code=$all_subs[1]; $self->$code();

      This will call $code as a method on $self, which AIUI is what you want. If you would like to do the same without an intermediate variable, then I wondered too and it turns out to be possible, albeit in a somewhat convoluted way.

        Worked great, but I did have to get rid of the & in front of my subroutine names. So:

        my @all_subs = (\sub_1,\sub_2);

        —Brad
        "The important work of moving the world forward does not wait to be done by perfect men." George Eliot