48

在 Perl 中,当我这样做时use <module name> <ver>;,系统会在路径.pm中的某处找到库的文件。@INC

是否有可靠的方法来实际加载哪个文件?

4

10 回答 10

71

是的,%INC包含加载模块的完整路径。

例子:

$ perl -M'Data::Dump qw(pp)' -e 'pp(\%INC)'
{
  "Data/Dump.pm"         => "/usr/share/perl5/Data/Dump.pm",
  "Exporter.pm"          => "/usr/share/perl/5.10/Exporter.pm",
  "List/Util.pm"         => "/usr/lib/perl/5.10/List/Util.pm",
  "Scalar/Util.pm"       => "/usr/lib/perl/5.10/Scalar/Util.pm",
  "XSLoader.pm"          => "/usr/lib/perl/5.10/XSLoader.pm",
  "overload.pm"          => "/usr/share/perl/5.10/overload.pm",
  "strict.pm"            => "/usr/share/perl/5.10/strict.pm",
  "vars.pm"              => "/usr/share/perl/5.10/vars.pm",
  "warnings.pm"          => "/usr/share/perl/5.10/warnings.pm",
  "warnings/register.pm" => "/usr/share/perl/5.10/warnings/register.pm",
}
于 2008-12-04T18:11:16.683 回答
9

如果模块有 pod 文档,并且您可以保证 PATH 中的 perldoc 实用程序属于运行脚本的同一个 perl,那么此命令通常会为您提供找到的实际文件:

perldoc -l ModuleName
于 2008-12-05T15:15:46.567 回答
9

perl -M'LWP' -e '使用数据::Dumper; 打印转储器 \%INC' | grep LWP

这将列出磁盘上的 LWP 模块位置,并列出在 LWP 中加载的模块。

      'LWP.pm' => '/usr/lib/perl5/5.10.0/LWP.pm',
      'LWP/Protocol.pm' => '/usr/lib/perl5/5.10.0/LWP/Protocol.pm',
      'LWP/UserAgent.pm' => '/usr/lib/perl5/5.10.0/LWP/UserAgent.pm',
于 2011-12-29T19:56:48.017 回答
7

您想查看变量,该变量记录了它为您使用、或%INC加载的库加载的文件名。有关详细信息,请参阅perlvardorequireuse

于 2008-12-04T21:03:00.330 回答
5

CPAN 中有很多模块可用于查找此信息,最有可能的候选模块是 Module::Find、Module::Which 和 Module::Locate。我可能会选择 Module::Locate:

use strict;
use warnings;
use Module::Locate qw/locate/;

my $to_find = "Some::Module";

print "Perl would use: ", scalar locate($to_find), "\n";

在列表上下文中,locate 根据 @INC 的顺序返回所有找到的 Some::Module 副本。

编辑: derobert 提出了一个更好的方法,我没有意识到 %INC 已经有了它......如果您想在加载要从中加载的模块之前知道这个基于模块的解决方案仍然很有用。

于 2008-12-04T18:10:56.590 回答
5

这是一个单行(带有 bash 包装器),用于确定是否安装了模块 - 以及将从何处加载它:

#!/bin/bash
perl -M${1} -le "\$mname=\"${1}.pm\";\$mname=~s#::#/#g;print \"$1 INSTALLED AT \$INC{\$mname}\";" 2>/dev/null || echo "${1} NOT INSTALLED"

使用 perl 的模块名称语法调用它:

./find_perl_module  Font::Metrics::Courier
于 2010-06-09T17:02:41.553 回答
2

根据我的发现,perl 将在路径中的目录中查找:

perl -le 'print foreach @INC'

然后它将在标准库中查找,然后在当前目录中查找。

这会给你一个搜索顺序。

我的来源:

扩展库路径

于 2008-12-04T17:53:31.833 回答
1

Module::Mapper提供了一种遍历 @INC 树来查找模块的方法:

perl -MModule::Mapper -MData::Dumper \
-e 'print Dumper( find_sources( UseINC => 1, Modules => [ @ARGV ] ) )' \
list-of-modules-to-locate
于 2008-12-04T18:22:50.277 回答
0

您可以使用 instmodsh 命令:http ://perldoc.perl.org/instmodsh.html 。

于 2012-01-16T09:50:58.877 回答
0

我使用 shell 脚本 /usr/local/bin/which_perl_module

#!/bin/sh

if [ ! $1 ];then echo "Which perl module should I look for?"; exit; fi

echo -n "You are using: "
perldoc -l $1
echo "which I found by looking in:"
perl -MData::Dump=pp -e 'unshift @INC, '$1'; pp(\@INC)'
于 2012-02-03T10:51:01.200 回答