ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП |
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы. |
12.13. Referring to Packages IndirectlyProblemYou want to refer to a variable or function in a package unknown until runtime, but syntax like Solution{ no strict 'refs'; $val = ${ $packname . "::" . $varname }; @vals = @{ $packname . "::" . $aryname }; &{ $packname . "::" . $funcname }("args"); ($packname . "::" . $funcname) -> ("args"); } DiscussionA 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 Prior to version 5 of Perl, programmers were forced to use an 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, printf "log2 of 100 is %.2f\n", log2(100); printf "log10 of 100 is %.2f\n", log10(100); Perl has only the natural log function. Here's how one could use $packname = 'main'; for ($i = 2; $i < 1000; $i++) { $logN = log($i); eval "sub ${packname}::log$i { log(shift) / $logN }"; die if $@; } Here, at least, you don't need to do that. The following code does the same thing, but instead of compiling a new function 998 times, we compile it only once, as a closure. Then we use symbolic dereferencing of the symbol table to assign the same subroutine reference to many function names: $packname = 'main'; for ($i = 2; $i < 1000; $i++) { my $logN = log($i); no strict 'refs'; *{"${packname}::log$i"} = sub { log(shift) / $logN }; } When you assign a reference to a typeglob, you create an alias just for the type of that name. That's how the Exporter does its job. The first line in the next code sample manually imports the function name *blue = \&Colors::blue; *main::blue = \&Colors::azure; Given the flexibility of typeglob assignments and symbolic references, a full-blown See AlsoThe section on "Symbolic References" in Chapter 4 of Programming Perl and in the start of perlsub (1); Recipe 11.4 |