Reputation: 2146
Please read this question carefully before replying, it is often misunderstood.
I need a way to check if a particular package exists in the current interpreter. I figured there might be a way to list all loaded packages, so that I can search in that list. Let's have an example. This is a simple script which defines several packages:
#!/path/to/perl
package Foo;
# some code in package Foo
package Bar;
# some code in package Bar
package main;
# main program. Want to have a list which includes 'Foo' and 'Bar'
As you can see, there's no use
or require
here. That's the point. I'm not looking for the modules installed on my system (those can be listed by traversing @INC
). Nor do I look for the modules that have been require
d (those are listed in %INC
). I want to have a list of packages which are available to the runtime, i.e. which have been defined with a package
statement. I guess it's equivalent to speak of a list of defined namespaces.
The thing is this. In a rather large project I often find myself refactoring the structure of my modules. That includes moving or renaming modules/packages. When renaming a module from Util::Foo
to Util::Bar
, 3 things have to be done.
Util/Foo.pm
to Util/Bar.pm
package Util::Foo;
to package Util::Bar;
use
clauses from use Util::Foo;
to use Util::Bar;
If I do steps 1 and 3, but forget to modify the package statement, the module Util::Bar
is loaded, but the package Util::Bar
is not defined. Rather, the Util::Foo
package is still defined. That leads to strange, incomprehensible warnings/errors when running the script. Perl won't point to the obvious error because defining a package within a module of another name is perfectly legal in Perl.
Another oddity I came across is when I have a case-sensitivity mistake in the use
clause. If I have a module FooBar
which correctly defines the package FooBar
, but I use
the module/package Foobar
(lowercase b), I get an instant error on a Unix system, because the module file is not found, but on a Windows system, a module file is found. If I then continue to use the wrong package name due to copy&paste, method-not-found errors arise which are hard to track down. Similarly, I had strange errors with respect to overridden methods from a superclass in a situation like this.
Upvotes: 6
Views: 401
Reputation: 8532
Walk the symbol table.
Start from %::
and look at all keys whose names themselves end in ::
, and recurse.
Upvotes: 6
Reputation: 118118
Use Devel::Symdump
require Devel::Symdump; @packs = qw(some_package another_package); $obj = Devel::Symdump->new(@packs); # no recursion $obj = Devel::Symdump->rnew(@packs); # with recursion # Methods @array = $obj->packages; @array = $obj->scalars; @array = $obj->arrays; @array = $obj->hashes; @array = $obj->functions; @array = $obj->filehandles; # deprecated, use ios instead @array = $obj->dirhandles; # deprecated, use ios instead @array = $obj->ios; @array = $obj->unknowns; # only perl version < 5.003 had some
Upvotes: 4