0

我有一个看起来像这样的目录结构:

Foo::Bar::Baz::1 Foo::Bar::Baz::2 等

我可以列出来自以下内容的软件包:

use Foo::Bar::Baz;

谢谢!

编辑:更清楚模块是什么。

4

4 回答 4

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请先进行任何所需的操作(例如使用 )。

于 2010-06-04T17:01:44.580 回答
1

通常,像 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)'
于 2010-06-04T17:00:38.877 回答
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;
}

自“require Inline”调用以来的新命名空间是:
        ::自动加载器::
        ::配置::
        ::消化::
        ::摘要::MD5::
        ::Dos::
        ::EPOC::
        ::出口商::
        ::出口商::重货::
        ::文件::
        ::文件::规格::
        ::文件::规范::Cygwin::
        ::文件::规范::Unix::
        ::文件::规范::Win32::
        ::内联::文件::
        ::内联::denter::
        ::标量::
        ::标量::实用程序::
        ::插座::
        ::VMS::
        ::VMS::文件规范::
        ::XSLoader::
        ::变量::
        ::警告::注册::
于 2010-06-04T17:36:12.163 回答
0

为了清楚起见,您是否正在查看随机 Perl 代码中的随机包?

或者对于 Perl模块,例如带有模块“a::b::c::d1”的“a/b/c/d1.pm”?

在任何一种情况下,您都不能使用单个“使用”语句来加载它们。

您需要做的是使用glob或找到所有适当的文件File::Find

在第一种情况下(模块),您可以通过require-ing 每个文件来加载它们,或者通过将文件名转换为模块名称 ( s#/#::#g; s#\.pm$##;) 并单独调用use每个模块。

至于嵌套在随机 Perl 文件中的实际包,这些包可以是:

  • 通过 grepping 每个文件(再次,通过globor找到File::Find)列出/^package (.*);/

  • require $file通过对每个文件执行实际加载。

    a/b/c/1.pl在这种情况下,请注意其中每个包的包名不需要与“a::b::c”相关 - 例如,它们可以由文件作者“p1”、“a:: p1”或“a::b::c::p1_something”。

于 2010-06-04T17:00:42.027 回答