我的目录结构如下:
富::酒吧::巴兹:: 1 Foo :: Bar :: Baz :: 2等
我可以列出以下内容的包:
use Foo::Bar::Baz;
谢谢!
编辑:更清楚模块是什么。
答案 0 :(得分:7)
如果您要使用特定前缀加载包含路径中的所有模块(例如a::b::c
下的所有模块,则可以使用Module::Find。
例如:
use Module::Find 'useall';
my @loaded = useall 'Foo::Bar::Baz'; # loads everything under Foo::Bar::Baz
这取决于您使用必要目录设置的@INC
路径,因此首先需要进行任何操作(例如使用use lib
)。
答案 1 :(得分:1)
通常,诸如/ b / c.pl之类的脚本不具有main
以外的命名空间。也许您正在考虑使用诸如a / b / c.pm之类的名称来发现 modules (这是一个坏名称,因为通常为Perl内部保留较低的包名称。)
但是,给定目录路径,您可以使用File::Find查找潜在的 Perl模块:
use strict;
use warnings;
use File::Find;
use Data::Dumper;
my @modules;
sub wanted
{
push @modules, $_ if m/\.pm$/
}
find(\&wanted, 'A/B');
print "possible modules found:\n";
print Dumper(\@modules)'
答案 2 :(得分:1)
这可能有点矫枉过正,但您可以在加载模块之前和之后检查符号表并查看更改内容:
use strict; use warnings;
my %original = map { $_ => 1 } get_namespaces("::");
require Inline;
print "New namespaces since 'require Inline' call are:\n";
my @new_namespaces = sort grep !defined $original{$_}, get_namespaces("::");
foreach my $new_namespace (@new_namespaces) {
print "\t$new_namespace\n";
}
sub get_namespaces {
# recursively inspect symbol table for known namespaces
my $pkg = shift;
my @namespace = ();
my %s = eval "%" . $pkg;
foreach my $key (grep /::$/, keys %s) {
next if $key eq "main::";
push @namespace, "$pkg$key", get_namespaces("$pkg$key");
}
return @namespace;
}
New namespaces since 'require Inline' call are: ::AutoLoader:: ::Config:: ::Digest:: ::Digest::MD5:: ::Dos:: ::EPOC:: ::Exporter:: ::Exporter::Heavy:: ::File:: ::File::Spec:: ::File::Spec::Cygwin:: ::File::Spec::Unix:: ::File::Spec::Win32:: ::Inline::Files:: ::Inline::denter:: ::Scalar:: ::Scalar::Util:: ::Socket:: ::VMS:: ::VMS::Filespec:: ::XSLoader:: ::vars:: ::warnings::register::
答案 3 :(得分:0)
为了清楚起见,您是否在随机Perl代码中查看随机包?
或Perl 模块,例如模块“a :: b :: c :: d1”的“a / b / c / d1.pm”?
在任何一种情况下,您都不能使用单个“use”语句来加载它们。
您需要做的是使用glob
或File::Find
找到所有相应的文件。
在第一种情况(模块)中,您可以通过require
- 每个文件加载它们,或者通过将文件名转换为模块名称(s#/#::#g; s#\.pm$##;
)并调用use
来加载它们每个模块都是单独的。
对于嵌套在随机Perl文件中的实际包,这些包可以是:
通过点击每个文件(再次通过glob
或File::Find
找到)列出/^package (.*);/
实际上是通过为每个文件执行require $file
来加载的。
在这种情况下,请注意a/b/c/1.pl
中每个软件包的软件包名称 NOT 需要与“a :: b :: c”相关 - 例如它们可以由文件作者“p1”,“a :: p1”或“a :: b :: c :: p1_something”命名。