给定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
我基本上想知道这些行是如何生成的。
程序是这样的:
.pm
个文件.pm
文件并打印出${ "${pkg}::VERSION"}
,其中$pkg
是与.pm
文件名对应的包名称(即.pm
文件名为Foo/Bar.pm
,$pkg
为Foo::Bar
。)是否有代码执行此索引过程?
你真的必须加载模块才能确定它的版本是什么吗?
答案 0 :(得分:4)
为PAUSE执行此操作的实际代码是on GitHub here。解析包和版本声明的子例程位于lib / PAUSE / pmfile.pm(packages_per_pmfile
和parse_version
)中。这对于使CPAN工作的情况具有权威性,但它不是你想要自己使用的代码 - 暂停已经差不多20年了,甚至在最近的一些清理工作之后仍然非常严重。
相反,请查看Module::Metadata。你给它一个文件,它提供了一个非常简单的接口来发现该文件中的包的名称以及它们的版本。
这很简单:
my $mm = Module::Metadata->new_from_file("My/Module.pm");
for my $package ($mm->packages_inside) {
print "$package: ", $mm->version($package), "\n";
}
事实上,这种“单线”有效:
find Acme-Chef-1.01 -name \*.pm \
| perl -MModule::Metadata -ln \
-e 'my $mm = Module::Metadata->new_from_file($_); ' \
-e 'print "$_: ", $mm->version($_) for $mm->packages_inside' \
| sort
和输出:
Acme::Chef: 1.01
Acme::Chef::Container: 1.00
Acme::Chef::Ingredient: 1.00
Acme::Chef::Recipe: 1.00