http://qs321.pair.com?node_id=11116512

nysus has asked for the wisdom of the Perl Monks concerning the following question:

This snippet of code will generate a list of symbols for a particular package, called PackageName:

sub dispSymbols { my($hashRef) = shift; my(%symbols); my(@symbols); %symbols = %{$hashRef}; @symbols = sort(keys(%symbols)); foreach (@symbols) { print Dumper printf("%-10.10s| %s\n", $_, $symbols{$_}); } } dispSymbols(\%PackageName::);

But let's say I want to discover all the different packages that I can use inside of the dispSymbols call. How can I generate a list of those top-level packages?

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

Replies are listed 'Best First'.
Re: How do I generate a list of available top-level packages?
by tobyink (Canon) on May 06, 2020 at 18:18 UTC

    Try this:

    dispSymbols(\%::);

    Or this:

    dispSymbols(\%main::);

    They should both do the same thing. Be aware that the main package does have a bunch of random stuff in it.

      Thanks. yeah, I see now I have to manually go through and pull the packages from that hairy hash manually.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

        I have to manually go through and pull the packages from that hairy hash manually.

        You can also use Devel::Symdump:

        use Devel::Symdump; my @packages = Devel::Symdump->rnew->packages;
Re: How do I generate a list of available top-level packages?
by jcb (Parson) on May 08, 2020 at 00:03 UTC

    You can get the top-level symbol tables with grep /::$/, keys %:: but that will not include second level or deeper packages. To get a list of all packages, you will need to recurse on each of those.

    Here is a simple one-liner for that:

    perl -e 'sub dp ($) {my $base = shift; my @nodes = map $base.$_, grep +/::$/, keys %{$base}; @nodes = grep !/^(?:::)?main::main/, @nodes if +$base =~ /^(?:::)?main/; print join(" ", @nodes),"\n"; dp($_) for @no +des}' -e 'dp "::"'

    Note the special handling due to :: and main:: being aliases and that this does not work if strict 'refs' is in effect.

Re: How do I generate a list of available top-level packages?
by nysus (Parson) on May 06, 2020 at 18:15 UTC

    I think the proper terminology is: how do I discover all the *symbol tables*.

    $PM = "Perl Monk's";
    $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
    $nysus = $PM . ' ' . $MCF;
    Click here if you love Perl Monks