If $package_name is just a top level package, this is easy:
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: use strict;
use Data::Dumper;
my $package_name = "Data";
print Dumper *{$::{$package_name."::"}}{HASH};
gives:$VAR1 = {
'Dumper::' => *{'Data::Dumper::'}
};
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:
use strict;
use Data::Dumper;
my $top_level = "Data";
my $second_level = "Dumper";
print Dumper *{${*{$::{$top_level."::"}}{HASH}}{$second_level."::"}}{H
+ASH}
gives:
$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
};
and you can look up a particular symbol in that and use it. To call Data::Dumper::Dumper, for instance, you can say:
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::);
calls Data::Dumper::Dumper via the symbol table and prints:
$VAR1 = {
'Dumper::' => *{'Data::Dumper::'}
};
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:
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::);
|