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

Oh great and venerable monks, I come to ye with a question of great significance.

I was wondering about discovering modules that have been previously loaded. In the codebase that I work to maintain and develop, we have a database access layer that consists of 150+ table wrappers that all are all sub-classed from a common class (let's call it A).

We have a script that will crawl the codebase directory structure to generate a Classes.pm that simply is a big list of 'use' statements for all of these table wrappers.

It would be beneficial if we had a way of getting the list of all loaded modules at run time without have to crawl a directory structure or parse any code files.

I have already worked out a way to determine whether or not a given module inherits from another. Now the question becomes, how can I get a listing of all modules that have been loaded?

I know that I could modify the script that produces the Classes.pm to also produce a list that is accessible from outside the package, and that would work for my purposes.

However, in thinking about about this problem I became interested to see what you guys would come up with in regards to the more general problem of discovering ALL modules that have been loaded.

One thought is to use %INC but that yields entries such as

'ICA/DB/Object/Facility.pm' => '/opt/A3AE/lib/ICA/DB/Object/ +Facility.pm', 'ICA/DB/Vault/Aggregator.pm' => '/opt/A3AE/lib/ICA/DB/Vault/ +Aggregator.pm',

And as we all know, perl allows you to have multiple packages in the same file, so the conventional mapping between 'ICA/DB/Object/Facility.pm' and 'ICA::DB::Object::Facility' cannot always be trusted.

I look forward to reading your responses.

¥peace from CaMelRyder¥

Replies are listed 'Best First'.
Re: Discovering Loaded Modules
by ikegami (Patriarch) on Jun 04, 2010 at 17:13 UTC
    You know the modules from %INC. It seems you want to know the packages in use. That can be done by visiting the symbol table tree.
    use strict; use warnings; sub visit { my ($parent, $table) = @_; for (keys(%$table)) { if (my ($trimmed) = /^(.*)::\z/s) { next if $_ eq 'main::'; print("$parent$trimmed\n"); visit("$parent$_", $table->{$_}); } } } visit('', \%::);

    The presence of &new, @ISA or &DESTROY would be a good indicator that the package is a class.

Re: Discovering Loaded Modules
by chromatic (Archbishop) on Jun 04, 2010 at 22:02 UTC
    Now the question becomes, how can I get a listing of all modules that have been loaded?

    Perhaps Devel::TraceUse is of value.

Re: Discovering Loaded Modules
by happy.barney (Friar) on Jun 05, 2010 at 05:47 UTC
    use Symbol::Table; $, = $\ = "\n"; print sort keys %{ New Symbol::Table PACKAGE => 'main'};