Item 57: Access the symbol table with typeglobs.


In the present implementation of Perl (and probablybut you never knowin all future implementations ) there is a symbol table entry for each unique identifier in a package. That entry contains slots for one of each of the possible types of valuesscalar, array, hash, filehandle, and so on. To a certain extent, you can directly manipulate the contents of the symbol table. One way to do this is with a construct called a typeglob. A typeglob is an identifier preceded by an asterisk, for example, *a . It represents the symbol table entry that contains all of the different types of values stored under that identifier.

A warning to the uninitiated: Typeglobs are generally considered to be an obscure feature. For that reason, you should avoid using them unnecessarily. Furthermore, you should avoid using typeglobs for tasks that could be handled with references (see Item 30), because references are far more efficient. With that admonition out of the way, let's move on.

You can use typeglobs to alias names :

 *ren = *stimpy; 

Make $ren an alias for $stimpy , @ren an alias for @stimpy , and so on.

 *main::ren = *main::stimpy; 

Same thing, explicit package name .

Typeglobs can be localized:

 local *ren = *stimpy; 

$ren , @ren , etc. are local.

A similar effect, but with run-time symbol table lookup, is available using the symbol table hash directly. Here is an example that manipulates the main package's symbol table:

 $::{'ren'} = $::{'stimpy'}; 

%:: is the main package's symbol table.

 local $::{'ren'} = $::{'stimpy'}; 

Can be localized.

You can pass typeglobs as arguments to subroutines, or store them like scalar values:

 @g = (*a, *b);  ($a, $b) = ("ren", "stimpy"); 

Storing typeglobs in an array.

 *s = $g[0];  *t = $g[1];  print "$s and $t\n"; 

Using them.

Or just (*s, *t) = @g .

Prints ren and stimpy .

You also can alias a single kind of variable, such as an array or subroutine only, by assigning a reference of the appropriate type to a typeglob:

 sub world { "world\n" }  *hello = \&world; 

Alias the name &hello to the subroutine &world .

 $hello = "hello";  print $hello . ", " . &hello; 

Prints hello, world .

You can use typeglobs to localize filehandles and directory handles (see Item 26):

 sub some_file_thing {    local *FH;    open FH, "foo";    ...  } 

FH is local to this subroutine.

You also can use typeglobs in places in which you would ordinarily use references (but avoid doing so unless you have to):

 sub yo { print "yo, world\n" };  &{*yo}(); 

Prints hello, world .

A recent addition to the language is the *FOO{BAR} or " typeglob subscript" syntax, which allows you to extract individual references from a typeglob:

 $a = "testing";  @a = 1..3;  $sref = *a{SCALAR};  $aref = *a{ARRAY};  print "$$sref @$aref\n"; 

Prints testing 1 2 3 .

Many of the things typeglobs were once used for now can be done more sensibly with references (see Item 30), packages, and/or object-oriented programming. However, you're likely to encounter them from time to time in older Perl code, so you should be aware of what they look like and what they do.



Effective Perl Programming. Writing Better Programs with Perl
Effective Perl Programming: Writing Better Programs with Perl
ISBN: 0201419750
EAN: 2147483647
Year: 1996
Pages: 116

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net