Hack #75. Find All Symbols in a Package
Explore symbol tables without soft references.
One of the earliest temptations
for novice programmers is to use the contents of one variable as part of the name of another variable. After making one too many costly mistakes or showing such code to a more experienced programmer, novices start to use the strict
pragma to warn them about dubious constructs.
However, several advanced features of Perl, such as the implementation of the Exporter
module, are only possible by reading from and writing to the symbol table at run time. Normally strict
forbids thisâbut it's possible to access global symbols at run time with strict
enabled.
This is an easy way to find out if a symbolâsuch as a scalar, array, hash, subroutine, or filehandleâexists.
The Hack
Suppose you want to check whether a specific type of variable is present in a given namespace. You need to know the name of the package, the name of the variable, and the type of the variable.
Defining the following subroutine in the UNIVERSAL
package makes the class method contains_symbol
available to any package:[4]
my %types = ( '$' => 'SCALAR', '@' => 'ARRAY', '%' => 'HASH', '*' => 'IO', '&' => 'CODE', ); sub UNIVERSAL::contains_symbol { my ($namespace, $symbol) = @_; my @keys = split( /::/, $namespace ); my $type = $types{ substr( $symbol, 0, 1, '' ) } || 'SCALAR'; my $table = \\%main::; for my $key (@keys) { $key .= '::'; return 0 unless exists $table->{$key}; $table = $table->{$key}; } return ...
Get Perl Hacks 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.