Perl 获得;定义为;CPAN dist文件中的模块?

Perl 获得;定义为;CPAN dist文件中的模块?,perl,cpan,Perl,Cpan,给定一个CPAN dist文件(如Acme-Chef-1.01.tar.gz),确定dist文件中“定义”(或存在)哪些模块版本的算法是什么 例如,在02packages.details.txt文件中,有四行对应于此dist文件: Acme::Chef 1.01 S/SM/SMUELLER/Acme-Chef-1.01.tar.gz Acme::Chef::Container 1.00 S/SM/SMUELLER/Ac

给定一个CPAN dist文件(如
Acme-Chef-1.01.tar.gz
),确定dist文件中“定义”(或存在)哪些模块版本的算法是什么

例如,在
02packages.details.txt
文件中,有四行对应于此dist文件:

Acme::Chef                         1.01  S/SM/SMUELLER/Acme-Chef-1.01.tar.gz
Acme::Chef::Container              1.00  S/SM/SMUELLER/Acme-Chef-1.01.tar.gz
Acme::Chef::Ingredient             1.00  S/SM/SMUELLER/Acme-Chef-1.01.tar.gz
Acme::Chef::Recipe                 1.00  S/SM/SMUELLER/Acme-Chef-1.01.tar.gz
我基本上想知道这些线是如何生成的

程序是否类似于:

  • 在dist文件中查找所有
    .pm
    文件
  • 加载每个
    .pm
    文件并打印出
    ${“${pkg}::VERSION”}
    ,其中
    $pkg
    是与
    .pm
    文件名相对应的包名(即,如果
    .pm
    文件名是
    Foo/Bar.pm
    $pkg
    Foo::Bar
  • 是否有执行此索引过程的代码


    您真的必须加载模块才能确定其版本吗?

    为暂停加载模块的实际代码是。解析包和版本声明的子例程位于lib/PAUSE/pmfile.pm(
    packages\u per\u pmfile
    parse\u version
    )中。就如何使CPAN工作而言,这是权威性的,但这并不是你想为自己使用的代码——PAUSE已经有将近20年的历史了,即使在最近的一些清理之后,它仍然相当糟糕

    相反,请看。您给它一个文件,它提供了一个非常简单的界面来发现该文件中包的名称及其版本

    简单到:

    my $mm = Module::Metadata->new_from_file("My/Module.pm");
    for my $package ($mm->packages_inside) {
        print "$package: ", $mm->version($package), "\n";
    }
    
    事实上,这种“一行”是有效的:

    和产出:

    Acme::Chef: 1.01
    Acme::Chef::Container: 1.00
    Acme::Chef::Ingredient: 1.00
    Acme::Chef::Recipe: 1.00
    

    它不执行模块;只有包含$version的行,您看到了吗?还有一行(大部分)只是
    Module::Metadata的包装。
    根据您的需要,
    Dist::Metadata
    可能有一个更合适的界面。但请注意,这些工具都不会始终生成与PAUSE完全相同的索引。除了实现上的细微差异之外,当前暂停索引还依赖于以前索引的所有分布。但在大多数情况下,
    Module::Metadata
    就足够了。这就是它的用途。
    Acme::Chef: 1.01
    Acme::Chef::Container: 1.00
    Acme::Chef::Ingredient: 1.00
    Acme::Chef::Recipe: 1.00