如何检查Perl模块是否已安装?

12

我正在编写一个小型的 Perl 脚本,它依赖于一些可能可用的模块,因此在安装过程中需要检查是否都已存在。我可以直接编写 use some::module 并查看是否出现错误,但对于最终用户来说,“您需要安装 some::module” 这样的简短信息会更有帮助。

我也可以搜索 @INC 中的每个目录,但由于这是 Perl,肯定要有更简单的方法。


1
如何检查Perl模块是否已安装并不是一个问题,而是一个陈述。 - cjk
5个回答

22
perl -MSome::Module -e ';'

糟糕,我误读了问题。 我以为你想知道一次性的情况,而不是以可恢复的方式发现它。 我总是使用这样的东西:

sub try_load {
  my $mod = shift;

  eval("use $mod");

  if ($@) {
    #print "\$@ = $@\n";
    return(0);
  } else {
    return(1);
  }
}

你可以像这样使用它:

$module = 'Some::Module';
if (try_load($module)) {
  print "loaded\n";
} else {
  print "not loaded\n";
}

1
在这里要注意,eval 执行了双重任务:它允许您检查任意模块,并防止 use 语句被转换为 BEGIN 块。结果是,如果您编写像这样的代码,但硬编码为特定模块,仍然会使用基于字符串的 eval。 - chaos
1
我喜欢你的回答,因为我想从bash中找出答案,但是我在需要参数的模块上遇到了麻烦。例如:[jens@ca60c173 (perl) p]$ perl -MPackage::DeprecationManager -e ';' 当导入Package::DeprecationManager时,您必须提供一个哈希引用-deprecations参数,在-e行0处。 - Jens Timmerman
一个快速的评论,虽然这很好,但它不适用于内联模块。 - Jacques

4
如何考虑:
die "Some::Module missing!" unless(eval{require Some::Module});

1
如果你要模仿使用并且添加一个结尾的话,你需要调用import。在结尾添加一个1是个好主意,因为import不需要返回真值:eval{require Some::Module; Some::Module->import; 1}。如果模块具有词法性质(如autobox),这也是不够的,因为它会在eval中导入,然后在eval结束时超出范围。 - Chas. Owens

2

我有一个小脚本,可以列出我系统上所有的Perl模块;

#!/usr/bin/perl

use ExtUtils::Installed;
my $instmod = ExtUtils::Installed->new();
foreach my $module ($instmod->modules()) {
    my $version = $instmod->version($module) || "???";
    print "$module -- $version\n";
}

在那个foreach循环内,您可能想要做一些类似于以下的事情;
my $match;
if ($module =~ /$match/) {
  print "Found $match: $module\n";
}

1

我使用类似这样的代码:

BEGIN { 
    my $module_name    = shift; # @ARGV
    our $module_exp = $module_name;
    eval "use $module_name;";
}

$module_exp =~ s{::}{/}g;
foreach my $key ( grep { m/^$module_exp\./ } keys %INC ) { 
    print "$key => $INC{$key}\n";
}

但我更多地将其用作Korn Shell函数的形式:

function wherperl
{
     perl -M$1 <<EX_DOC
     my \$module = '$1';
     \$module =~ s/::/\\//g;

     for ( keys %INC ) {
         next unless m/^\$module\./;
         print \$_ . ' => ' . \$INC{\$_} . "\n";
     }
EX_DOC
}

0

我喜欢使用cpan实用程序:

% cpan -D YAML
YAML
-------------------------------------------------------------------------
    YAML Ain't Markup Language (tm)
    A/AD/ADAMK/YAML-0.70.tar.gz
    /usr/local/perls/perl-5.10.0/lib/site_perl/5.10.0/YAML.pm
    Installed: 0.68
    CPAN:      0.70  Not up to date
    Ingy dot Net (INGY)
    ingy@cpan.org

这可能会有点慢,因为它需要连接到CPAN镜像来获取某些数据,但我也有一个本地的CPAN镜像。 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接