Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Accessing list of package names in a module

by FreakyGreenLeaky (Sexton)
on Nov 20, 2008 at 09:17 UTC ( #724825=perlquestion: print w/ replies, xml ) Need Help??
FreakyGreenLeaky has asked for the wisdom of the Perl Monks concerning the following question:

Greetings, I'm looking for a clean way (ie, without using a shell call, grepping, etc) to obtain the list of package names in a module from a calling script. For example, given the following module (Util/Stuff.pm):
package Util::Stuff; use strict; use warnings; package Util::Stuff::aaa1; sub flag { 1 } ... package Util::Stuff::aaa2; sub flag { 0 } ... package Util::Stuff::aaa3; sub flag { 1 } ... ... 1;
I now want to obtain the list programmatically:
Util::Stuff:aaa1 Util::Stuff:aaa2 Util::Stuff:aaa3
Once I have that info in a list, I want to get the flag values: The manual/existing way:
use Util::Stuff; my $temp1 = Util::Stuff::aaa1->flag; my $temp2 = Util::Stuff::aaa2->flag; my $temp3 = Util::Stuff::aaa3->flag;
The way I'd like:
use Util::Stuff; my @names = **get_package_names(Util::Stuff)** foreach my $name (@names) { push @temp, $name->flag;' }
Any pointers would be appreciated.


Regards
Henry

Comment on Accessing list of package names in a module
Select or Download Code
Re: Accessing list of package names in a module
by Anonymous Monk on Nov 20, 2008 at 09:31 UTC
    my $source = do { local(*ARGV, $/); @ARGV = $INC{'Util/Stuff.pm'}; <>; }; my @packages = $source =~ m/package\s+[_a-zA-Z][^\S;]*;/g;
    I would use Module::Info
    my $mod = Module::Info->new_from_module('Some::Module'); my @packages = $mod->packages_inside;
      Thanks, Module::Info looked ideal, but it doesn't correctly return all the package names from a module (it only returns the last for some reason).

      I'll give the first sample a try now.
        You should report that bug.
Re: Accessing list of package names in a module
by LanX (Canon) on Nov 20, 2008 at 10:03 UTC

    Just one remark for better understanding: Each imported package is listed in the namespace symbol table of the importing package.

    so by scanning the namespaces starting from the root "main" you should find the desired infos. Packages are keys ending with a "::".

    use Data::Dumper; print Dumper \%:: ;
    you will see entries like 'Data::' => *{'::Data::'},

    so recursively you can get all the infos you want.

    Cheers LanX

    UPDATE:

    Note:

    • %:: is a abbreviation for %main::
    • "%packagename::" is known as "stash" = symbol table hash
      Aah, that's the one. Nice and simple and takes advantage of goodies hidden internally . Thank you!
        Symbol tables are hardly "goodies hidden internally", they are documented in perlmod.

        Though if you come from other programming languages it's not obvious that something like that even exists :-)

Re: Accessing list of package names in a module
by Crian (Chaplain) on Nov 20, 2008 at 10:46 UTC

    If you want to analyse foreign modules, you should think of the possibility of functions created by autoload. I don't know how to fetch them too.

      If AUTOLOAD stores them in the symbol table, they'll be in the symbol table. If AUTOLOAD doesn't (and you didn't predeclare them), you won't.

Re: Accessing list of package names in a module
by sathiya.sw (Monk) on Nov 20, 2008 at 14:38 UTC
    Simple, go for Devel::Symdump which dumps your symbol table.
    For your first requirement, use packages method in that.
    I think simple, and straight way
    Is It ?

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://724825]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2014-10-25 00:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (138 votes), past polls