我有一个看起来像这样的目录结构:
Foo::Bar::Baz::1 Foo::Bar::Baz::2 等
我可以列出来自以下内容的软件包:
use Foo::Bar::Baz;
谢谢!
编辑:更清楚模块是什么。
我有一个看起来像这样的目录结构:
Foo::Bar::Baz::1 Foo::Bar::Baz::2 等
我可以列出来自以下内容的软件包:
use Foo::Bar::Baz;
谢谢!
编辑:更清楚模块是什么。
如果你想在你的包含路径中加载所有带有特定前缀的模块(例如,下面的所有内容a::b::c
,你可以使用Module::Find。
例如:
use Module::Find 'useall';
my @loaded = useall 'Foo::Bar::Baz'; # loads everything under Foo::Bar::Baz
这取决于您的@INC
路径是否设置了必要的目录,因此use lib
请先进行任何所需的操作(例如使用 )。
通常,像 a/b/c.pl 这样的脚本不会有除main
. 也许您正在考虑发现名称为 a/b/c.pm 的模块(这是一个不好的名称,因为小写的包名称通常是为 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)'
这可能有点矫枉过正,但您可以在加载模块之前和之后检查符号表,看看发生了什么变化:
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;
}
自“require Inline”调用以来的新命名空间是: ::自动加载器:: ::配置:: ::消化:: ::摘要::MD5:: ::Dos:: ::EPOC:: ::出口商:: ::出口商::重货:: ::文件:: ::文件::规格:: ::文件::规范::Cygwin:: ::文件::规范::Unix:: ::文件::规范::Win32:: ::内联::文件:: ::内联::denter:: ::标量:: ::标量::实用程序:: ::插座:: ::VMS:: ::VMS::文件规范:: ::XSLoader:: ::变量:: ::警告::注册::
为了清楚起见,您是否正在查看随机 Perl 代码中的随机包?
或者对于 Perl模块,例如带有模块“a::b::c::d1”的“a/b/c/d1.pm”?
在任何一种情况下,您都不能使用单个“使用”语句来加载它们。
您需要做的是使用glob
或找到所有适当的文件File::Find
。
在第一种情况下(模块),您可以通过require
-ing 每个文件来加载它们,或者通过将文件名转换为模块名称 ( s#/#::#g; s#\.pm$##;
) 并单独调用use
每个模块。
至于嵌套在随机 Perl 文件中的实际包,这些包可以是:
通过 grepping 每个文件(再次,通过glob
or找到File::Find
)列出/^package (.*);/
require $file
通过对每个文件执行实际加载。
a/b/c/1.pl
在这种情况下,请注意其中每个包的包名不需要与“a::b::c”相关 - 例如,它们可以由文件作者“p1”、“a:: p1”或“a::b::c::p1_something”。