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); ...
Get Perl Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.