1

编辑

为了让其他对此问题感到困惑的人受益,我已在此处添加了解释的前缀。正如@Ikegami 解释的那样,

  • VERSION_FROM指示发行版的版本来自哪里,如果不在顶级模块中;
  • PREREQ_PM指示(可选)每个所需模块的版本

一个带有版本号的发行版通常由几个模块组成,每个模块都有自己的版本号,与发行版的编号不同。

另一方面,由单个文件中的单个模块组成的发行版不需要利用VERSION_FROM.

但是,对于中间情况:

  • 应具有相同版本号的多个模块和程序的分布,以及
  • 有足够多的文件或程序,将版本号放入一个单独的文件是有利的

那么,下面描述的 hack 可能对您有用。

希望对某人有所帮助!

原始问题

实际上,我在 ExtUtils::MakeMaker 的 POD 中看到的第一件事是VERSION_FROM,这表明可以,甚至应该使用它。但是,即使 MakeMaker 本身也看不到先决条件的版本(用 列出PREREQ_PM),除非它位于顶级模块中。也就是说,如果我设置了另一个需要特定版本 Foo 的模块 Bar,其中 Foo 将其版本定义为 Foo.pm 以外的某个位置,MakeMaker 将报告 Foo 的版本为未知。

似乎是一个如此明显且长期存在的错误,让我想知道我是否只是误解或滥用它?

编辑问题是:为什么MakeMaker在不使用它来获取版本时鼓励VERSION_FROM?

编辑以下是一个可能有问题的解决方法,而不是主要问题:

OTOH,ExtUtils::MM_Unix 中检查版本的代码绝不会在任何地方VERSION_FROM显示。但是,它确实表明了一个有趣的解决方法。

如果模块 Foo 在 Makefile.PM 中有:

WriteMakefile(
  NAME=>'Foo',
  VERSION_FROM => 'lib/Foo/Version.pm',
  ...

lib/Foo/Version.pm 显然有

use vars qw($VERSION);
$VERSION = '0.1';

然后在 Foo.pm 中输入:

$Foo::VERSION = do { use Foo::Version; $Foo::Version::VERSION; };

一切正常......现在!

那么,这是 MakeMaker 中的一个错误吗?和/或我的解决方法是否合理(按照 Perl 标准)?

谢谢

4

2 回答 2

1

$VERSION变量显然与任何其他变量一样,因此您可以以富有想象力的方式设置它,例如:

$Foo::VERSION = do { use Foo::Version; $Foo::Version::VERSION; };

或者:

$Foo::VERSION = grep /[aeiou]/, 'a'..'z';   # version five

但是,很多工具链模块(包括 ExtUtils::MakeMaker)不会执行您的文件来查找版本号。相反,他们会遍历它的行并尝试寻找看起来像数字的东西被分配给看起来像变量的东西$VERSION,并猜测该数字是模块的版本。当然,这并不理想,但这就是我们生活的世界。

要让这些工具正常工作,您需要确保以一种非常简单的方式设置您的版本号,例如:

$Foo::VERSION = '1.001';

如果你有很多模块,并且担心同时更新所有模块的版本号,那么安装Perl::Version捆绑了一个名为的脚本perl-reversion,它可以很容易地更新一堆模块中的版本号一气呵成。

于 2014-02-13T13:37:06.390 回答
0

在这种情况下,“有效”是指在尝试构建假设的包“Bar”时,MakeMaker 会意识到 Foo 的版本为 0.1。

VERSION_FROM指定从何处获取发行版的版本。它不设置任何模块的版本。

PREREQ_PM定义模块列表和(根据它们的名称和版本)分发所需的。

模块的版本可能与它所在的发行版的版本不同。模块 Foo 没有版本,这就是为什么要求模块 Foo 的 0.1 版(正确)失败的原因。

于 2014-02-16T02:11:30.333 回答