6

我想获取包含模块的完整文件名。考虑这段代码:

package MyTest;

my $path = join '/', split /::/, __PACKAGE__;
$path .= ".pm";

print "$INC{$path}\n";

1;

$ perl -Ipath/to/module -MMyTest -e0
path/to/module/MyTest.pm

它可以在所有平台上运行吗?

perlvar

哈希%INC包含通过 、 或 运算符包含的每个文件名dorequire条目use。键是您指定的文件名(模块名称转换为路径名),值是找到的文件的位置。

这些键是否依赖于平台?我应该使用File::Spec还是什么?至少 Win32 上的 ActivePerl 使用/而不是\.

更新:%INC价值观呢?它们是否依赖于平台?

4

2 回答 2

2

鉴于它是一个标准模块,请使用Module::Loaded的方法:

sub is_loaded (*) { 
    my $pm      = shift;
    my $file    = __PACKAGE__->_pm_to_file( $pm ) or return;

    return $INC{$file} if exists $INC{$file};

    return;
}

sub _pm_to_file {
    my $pkg = shift;
    my $pm  = shift or return;

    my $file = join '/', split '::', $pm;
    $file .= '.pm';

    return $file;
}
于 2010-02-23T15:03:06.723 回答
1

这是一个相当健壮的实现,它也适用于尚未加载的模块。

use File::Find;
use File::Spec;

sub pkg2path (*) {
    my $file = join '[\\\/:]' =>
               map  "\Q$_"    =>
               split /::|'/   => "$_[0].pm";            # '

    /$file$/ and return File::Spec->rel2abs( $INC{$_} )
        for keys %INC;

    # omit the rest to only find loaded modules

    my $path; find {
        no_chdir => 1,
        wanted   => sub {
            $path = $_ and goto found if /$file$/
        }
    } => @INC;

    found: File::Spec->rel2abs($path or return)
}

say pkg2path Benchmark;
say pkg2path Devel::Trace;
于 2010-02-26T21:36:45.603 回答