in reply to Symbol table dereference
First of all, the main symbol table %:: (aka %main::) is a hash; you want to look up the key named $package_name."::" (assuming $package_name doesn't already have the all-important trailing ::). This is just $::{$package_name."::"}.
Now, the values in a symbol table are globs (with the exception of declared-but-not-defined subs, which are scalars giving prototype information); you want to get the hash reference out of the glob. This is done with the *FOO{THING} syntax (enclosing our FOO in {} since its an expression that evaluates to a glob, not a simple glob name): *{$::{$package_name."::"}}{HASH}.
Voila:
gives:use strict; use Data::Dumper; my $package_name = "Data"; print Dumper *{$::{$package_name."::"}}{HASH};
You can then go ahead and use that hash ref to get a nested package, look up a glob in it, and extract a hash reference from it:$VAR1 = { 'Dumper::' => *{'Data::Dumper::'} };
gives:use strict; use Data::Dumper; my $top_level = "Data"; my $second_level = "Dumper"; print Dumper *{${*{$::{$top_level."::"}}{HASH}}{$second_level."::"}}{H +ASH}
and you can look up a particular symbol in that and use it. To call Data::Dumper::Dumper, for instance, you can say:$VAR1 = { 'Seen' => *Data::Dumper::Seen, 'post' => *Data::Dumper::post, 'Toaster' => *Data::Dumper::Toaster, 'Varname' => *Data::Dumper::Varname, 'pad' => *Data::Dumper::pad, 'Values' => *Data::Dumper::Values, 'Dumpf' => *Data::Dumper::Dumpf, 'new' => *Data::Dumper::new, '_sortkeys' => *Data::Dumper::_sortkeys, 'Pair' => *Data::Dumper::Pair, 'DESTROY' => *Data::Dumper::DESTROY, 'EXPORT_OK' => *Data::Dumper::EXPORT_OK, 'Pad' => *Data::Dumper::Pad, 'confess' => *Data::Dumper::confess, 'Deepcopy' => *Data::Dumper::Deepcopy, 'EXPORT_FAIL' => *Data::Dumper::EXPORT_FAIL, 'Sortkeys' => *Data::Dumper::Sortkeys, 'Freezer' => *Data::Dumper::Freezer, 'ISA' => *Data::Dumper::ISA, 'Terse' => *Data::Dumper::Terse, 'Maxdepth' => *Data::Dumper::Maxdepth, 'Dumpp' => *Data::Dumper::Dumpp, 'Useperl' => *Data::Dumper::Useperl, 'Dumpxs' => *Data::Dumper::Dumpxs, 'bootstrap' => *Data::Dumper::bootstrap, '_dump' => *Data::Dumper::_dump, 'qquote' => *Data::Dumper::qquote, 'Useqq' => *Data::Dumper::Useqq, 'BEGIN' => *Data::Dumper::BEGIN, 'Purity' => *Data::Dumper::Purity, 'Names' => *Data::Dumper::Names, 'Deparse' => *Data::Dumper::Deparse, 'EXPORT' => *Data::Dumper::EXPORT, 'DumperX' => *Data::Dumper::DumperX, 'croak' => *Data::Dumper::croak, 'Dump' => *Data::Dumper::Dump, 'import' => *Data::Dumper::import, 'Indent' => *Data::Dumper::Indent, 'Dumper' => *Data::Dumper::Dumper, 'Quotekeys' => *Data::Dumper::Quotekeys, 'Bless' => *Data::Dumper::Bless, 'carp' => *Data::Dumper::carp, 'VERSION' => *Data::Dumper::VERSION, 'Reset' => *Data::Dumper::Reset, 'Dumpperl' => *Data::Dumper::Dumpperl };
calls Data::Dumper::Dumper via the symbol table and prints:use Data::Dumper; my $top_level = "Data"; my $second_level = "Dumper"; my $subname = "Dumper"; print &{*{${*{${*{$::{$top_level."::"}}{HASH}}{$second_level."::"}}{HA +SH}}{$subname}}{CODE}}(\%Data::);
Actually, a lot of the above can be much simplified, because of an odd rule that says you can put a glob where a reference of a particular type is wanted, and it automatically produces the reference to that part of the glob:$VAR1 = { 'Dumper::' => *{'Data::Dumper::'} };
use strict; use Data::Dumper; my $package_name = "Data"; print Dumper \%{$::{$package_name."::"}}; use strict; use Data::Dumper; my $top_level = "Data"; my $second_level = "Dumper"; print Dumper \%{${$::{$top_level."::"}}{$second_level."::"}}; use Data::Dumper; my $top_level = "Data"; my $second_level = "Dumper"; my $subname = "Dumper"; print &{${${$::{$top_level."::"}}{$second_level."::"}}{$subname}}(\%Da +ta::);
|
|---|