【问题标题】:How can I tell if a Perl module is core or part of the standard install?如何判断 Perl 模块是核心还是标准安装的一部分?
【发布时间】:2011-01-04 05:14:16
【问题描述】:

如何检查 Perl 模块是否是核心的一部分 - 即它是否是标准安装的一部分?

我正在寻找:

  • 命令行命令:
  • 在代码中检查的 Perl 子例程/函数

也许问题应该是:我如何知道机器上的特定 Perl 安装最初提供了哪些模块? (其实现在问的是How can I tell what modules were originally provided with the specific Perl installation on a machine?。)

鉴于现在似乎没有一个整体的 Perl 标准安装,至少这个新问题的答案会告诉我第一次安装时我在安装中最初的内容。

有了这些知识,并且如果我保留原始安装程序映像/包或知道如何再次在线获取确切的内容,那么我可以为多台机器重复安装 Perl,并且知道哪些模块将存在以及哪些模块将存在不是。

进一步澄清:我正在查看最初的安装,作为该安装的一部分提供了哪些模块,以及内置的。 没有从那以后安装了什么。

而且我希望能够在安装了该设备的机器上执行此操作。因此,为此,我将依靠安装以某种形式记录它最初的内容。

我问了一个衍生问题: How can I tell what modules were originally provided with the specific Perl installation on a machine?(我如何知道机器上的特定 Perl 安装最初提供了哪些模块?)

【问题讨论】:

  • 所有 Debian 平台?所有相同的 Debian 版本?我们需要做到什么程度?
  • 什么平台都没有关系。我在这个新问题(标题为“更新”下)中寻找的是一段通用代码,我可以使用它在特定机器上运行以确定哪些模块最初是该特定机器上 Perl 安装的一部分。不管是 Debian 4,5 还是 Ubuntu 还是 Mandriva 等等。
  • 当您要彻底改变一个问题时,只需提出一个新问题。您可以提出的问题数量没有限制。 :)
  • @brian d foy:+1 感谢您的鼓励:我已经问过这个问题stackoverflow.com/questions/2085516/…

标签: perl module standard-library


【解决方案1】:

真的没有“核心”这样的东西了。曾经有一个标准的 Perl 发行版,但是很多人没有一个标准的 Perl 发行版。操作系统发行版通过添加或删除模块、更改模块等来修改它。您不能依赖标准发行版实际上是标准的。一些 Linux 发行版甚至没有将 Perl 文档作为基本 Perl 安装的一部分。

您提到您不能使用Module::CoreList,因为它不是核心,但如果您可以创建文件,则可以安装该模块。你甚至可以假装是你自己写的。

【讨论】:

  • 谢谢+1。从你自己和其他人的有用反馈中,我开始得出结论,我的问题没有黑白简单的答案。我将不得不忍受这种情况并解决它或提出更好的问题。
  • 这并不是不能使用 Module::CoreList 的情况,如果可以避免的话,我更不想这样做。我想看看是否有一个内置功能,并且保证在每个 Perl 安装中都存在,比如关键字 print、open 等。现在看来这不太可能。理想情况下,我宁愿不必更改正在检查核心模块的系统状态(即通过安装 Module::CoreList)。我不想改变我正在测量的内容。
  • 当然也同意我不能“依赖标准发行版实际上是标准的”并且“某些 linux 发行版甚至不包含 Perl 文档作为基本 Perl 安装的一部分”:我的Debian 4 发行版并没有什么特别之处,只是简单的 Debian 安装,这意味着我无法尝试另一张海报建议的 perlmodlib 解决方案。
  • 如果你在写程序,你就是在改变状态。 Module::CoreList 只是代码。谁写的并不重要。
  • 这确实应该是一个新问题。
【解决方案2】:

您可以使用(例如,搜索Net::FTP):

perl -MNet::FTP -e 1

如果没有输出,则说明已安装。

其他资源

perldoc perlmodlib 
perldoc perllocal

A node from perlmonks

【讨论】:

  • 另外,perldoc -l Net::FTP 并检查它是否在 core-dir、site-dir 或 vendor-dir 中?
【解决方案3】:
  • 从命令行:

    假设你想知道 模块Tie::Hash 是否为 安装。
    要找出答案,请执行 命令行中的以下内容:

    perl -MTie::Hash -e 1
    

    如果您没有从上述命令中得到任何输出,则该模块已安装;如果出现错误,则说明未安装。

  • 要在脚本中进行此检查,您可以使用Module::Load::Conditional

【讨论】:

  • 请记住,这些方法不区分核心模块和非核心模块,如 perlmodlib 所定义。这些方法将检查所有已安装的模块。
【解决方案4】:

在回复 Gbacon 的评论时,您说您希望答案是平台中立的。我不知道这样的解决方案,但我想知道这是否是正确的方法。

如果您的目标是在特定机器上进行查找,我会使用平台附带的工具。在 Debian 上,这将包括 dpkg(预安装在任何 Debian 系统上)或 apt-file(不一定预安装)或其他 APT 工具。

作为一个例子,看看这个的输出:

dpkg-query -L perl | less

您显然需要解析输出,但正是因为它特定于所讨论的机器。

【讨论】:

    【解决方案5】:

    您可以在 sub 中查看perlmodlib

    my %_stdmod;
    sub is_standard_module {
      my($module) = @_;
    
      unless (keys %_stdmod) {
        chomp(my $perlmodlib = `perldoc -l perlmodlib`);
        die "cannot locate perlmodlib\n" unless $perlmodlib;
    
        open my $fh, "<", $perlmodlib
          or die "$0: open $perlmodlib: $!\n";
    
        while (<$fh>) {
          next unless /^=head\d\s+Pragmatic\s+Modules/ ..
                      /^=head\d\s+CPAN/;
    
          if (/^=item\s+(\w+(::\w+)*)/) {
            ++$_stdmod{ lc $1 };
          }
        }
      }
    
      exists $_stdmod{ lc $module } ? $module : ();
    }
    

    示例用法:

    die "Usage: $0 module..\n" unless @ARGV;
    
    foreach my $mod (@ARGV) {
      my $stdmod = is_standard_module $mod;
      print "$0: $mod is ", ($stdmod ? "" : "not "), "standard\n";
    }
    

    输出:

    $ ./isstdmod threads::shared AnyDBM_File CGI LWP::Simple
    ./isstdmod:threads::shared 是标准的
    ./isstdmod: AnyDBM_File 是标准的
    ./isstdmod:CGI 是标准的
    ./isstdmod: LWP::Simple 不是标准的

    perldoc 绝对是 Perl 真正核心和标准安装的一部分。例如,perl-5.10.1 的源代码分发包含

    • perldoc.PL,生成 perldoc 作为标准安装的一部分
    • perlmodlib.PL,生成 perlmodlib.pod 作为标准安装的一部分

    这不是新增内容。大约十年前的 Perl-5.6.0,将 perlmodlib 作为其真正核心的标准安装的一部分。

    不包含这些项目的安装是非标准的。是的,我很欣赏从您的角度来看这似乎是学术性的,但是您的供应商的包装允许进行非标准安装,这会破坏其他工作程序。

    使用 Debian 的包管理器,您可以获得标准的 Perl 安装

    $ apt-get --install-recommends install perl

    【讨论】:

    • 这个答案看起来比 Module::CoreList 更有利,因为我假设 perlmodlib 在 Module::CoreList 不可用的早期 Perl 版本中可用作核心/标准。
    • 更新:在我的 Debian 4 Linux /var/log/apache2/error.log 日志中出现错误:[Wed Jan 13 11:05:15 2010] [error] [client 10.0.97.142] 你需要安装 perl-doc 包才能使用这个程序。 [2010 年 1 月 13 日星期三 11:05:15] [错误] [客户端 10.0.97.142] 找不到 perlmodlib 所以我必须安装一些东西来让它工作!再次同我的 cmets 对 toolic 的回答:“理想情况下,这应该是 Perl 的真正核心,在早期版本中,作为内置函数,如打印、打开、关闭等。” =
    • 补充一点:检查其他事物是否是核心/标准的东西本身不应该是非核心/标准的。
    • 很抱歉不能说它有效。我想。但鉴于目前的结果,我目前还不能。
    • Perl 的源代码告诉我们标准安装中有什么。这是无可争辩的,所以让我们转向一个更相关的问题:你最终想要做什么?
    【解决方案6】:

    来自Module::CoreList 模块的corelist 命令将确定模块是否为核心。

    > corelist Carp
    
    Carp was first release with perl 5
    
    > corelist XML::Twig
    
    XML::Twig was not in CORE (or so I think)
    

    这是在脚本中使用它的一种方法。 Module::CoreList POD 太简洁了——你必须翻遍源代码才能找到要调用的方法:

    use strict;
    use warnings;
    use Module::CoreList;
    
    my $mod = 'Carp';
    #my $mod = 'XML::Twig';
    my @ms = Module::CoreList->find_modules(qr/^$mod$/);
    if (@ms) {
        print "$mod in core\n";
    }
    else {
        print "$mod not in core\n";
    }
    
    __END__
    
    Carp in core
    

    【讨论】:

    • 不错。我之前使用过 CPAN shell "i" 命令来获取信息,但 corelist 看起来更好。双活模块的“DSLIP_STATUS”似乎不可信——一些标准模块说“已发布”而不是“标准”。例如,“i CGI”显示了 Stein 的 CPAN 版本(RdpOp 发布,开发者,perl,面向对象,Standard-Perl),尽管它是 Perl 的标准。
    • 谢谢,但是 Module::CoreList 本身是一个核心模块,可以保证在任何标准 Perl 安装中都存在吗?
    • Module::CoreList 是截至 5.009002 (2005-Apr-01) 的核心模块,根据perldoc.perl.org/perl592delta.html。从那时起,应该保证它是任何正确安装的 Perl 的一部分,但不是之前。
    • 出于实用目的,“since 5.9.2”对于普通人来说意味着“since 5.10.0”:)
    • 感谢您回答 toolic +1 的评论。
    【解决方案7】:

    对于真正的懒人,perldoc.perl.org 网站上有 Core Modules list

    【讨论】:

    • 这个答案不满足任何要求。这甚至不是最简单的事情。
    • @brian d foy:是的,我故意忽略了这些要求,因为它们是不必要的。现在问题已经更新,这个答案仍然有效,因为它仍然可以让您合理预期哪些模块应该在默认的 perl 安装中,而不需要安装额外的模块。
    • +1 @R。 Bemrose:我绝对同意这是一个“合理的期望”!我可能会将更新后的问题单独发布以提供更多可见性,因为它的不同足以从一些其他发帖人的答案中受益。
    猜你喜欢
    • 2019-11-19
    • 1970-01-01
    • 1970-01-01
    • 2023-01-31
    • 1970-01-01
    • 2014-05-06
    • 2012-11-03
    • 2012-07-05
    • 2013-07-02
    相关资源
    最近更新 更多