O'Reilly logo

Perl Cookbook by Nathan Torkington, Tom Christiansen

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Referring to Packages Indirectly

Problem

You want to refer to a variable or function in a package unknown until runtime, but syntax like $packname::$varname is illegal.

Solution

Use symbolic references:

{
    no strict 'refs';
    $val  = ${ $packname . "::" . $varname };
    @vals = @{ $packname . "::" . $aryname };
    &{ $packname . "::" . $funcname }("args");
    ($packname . "::" . $funcname) -> ("args");
}

Discussion

A package declaration has meaning at compile time. If you don’t know the name of the package or variable until run time, you’ll have to resort to symbolic references for direct access to the package symbol table. Assuming you normally run with use strict in effect, you must disable part of it to use symbolic references. Once you’ve used the no strict 'refs' directive in that block, build up a string with the fully qualified name of the variable or function you’re interested in. Then dereference this name as though it were a proper Perl reference.

Prior to version 5 of Perl, programmers were forced to use an eval for this kind of thing:

eval "package $packname; \$'$val = \$$varname"; # set $main'val
die if $@;

As you see, this approach makes quoting difficult. It’s also comparatively slow. Fortunately, you never need to do this just to access variables indirectly by name. Symbolic references are a necessary compromise.

Similarly, eval could be used to define functions on the fly. Suppose you wanted to be able to get the base 2 or base 10 logs of numbers:

printf "log2 of 100 is %.2f\n", log2(100); ...

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required