【问题标题】:perl MakeMaker's version_from not used by prereq_pmperl MakeMaker 的 version_from 未被 prereq_pm 使用
【发布时间】:2014-02-12 17:46:30
【问题描述】:

编辑

我在此处添加了解释的前缀,以方便其他对此问题感到困惑的人。 正如@Ikegami 解释的那样,

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

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

在频谱的另一端,由单个模块组成的分布 文件不需要利用VERSION_FROM

但是,对于中间情况:

  • 应具有相同版本号的多个模块和程序的分布,并且
  • 有足够多的文件或程序在其中放置版本是有利的 编号到一个单独的文件中

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

希望对某人有所帮助!

原始问题

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

似乎是一个如此明显且长期存在的错误,让我怀疑我是否 只是误解或误用?

EDIT 问题是:为什么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 标准)?

谢谢

【问题讨论】:

  • 你展示了什么有效,但我不清楚什么无效
  • 除非你把那个 dubious hack 放在 Foo.pm 中,否则它是行不通的; MakeMaker POD 或其他地方没有暗示需要这样的东西。
  • “它不起作用”没有澄清任何事情。什么”?你得到了什么你认为不可接受的结果?
  • “It doesn't work”指的是第1段的结论,即MakeMaker报告Foo的版本为未知。在这种情况下,“有效”是指在尝试构建假设的包“Bar”时,MakeMaker 会意识到 Foo 的版本为 0.1。
  • 你没有给我加标签,所以我没有收到你的评论通知。

标签: perl makemaker


【解决方案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 的脚本捆绑在一起,这使得更新版本号变得非常容易一口气在一堆模块中。

【讨论】:

  • MakeMaker 不执行 file,但它确实执行包含 $VERSION 的行,令人惊讶。但这不是问题:请参阅上面的编辑。
【解决方案2】:

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

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

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

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

【讨论】:

  • 啊哈!确实,这是关键的(即使是微妙的)区别,而且事实上,它存在于 ExtUtils::MakeMaker POD 中,如果人们有足够的洞察力来识别它。此外,既然你提出来了,我可以看出这种区别对于 Perl 发行版和模块来说是必要且有用的。
  • 但是,我认为我的用例:distribution == large collection of modules ALL with the same version也是一个有用的,而且我知道我不是第一个偏离轨道的人.您是否觉得我的“解决方法”是实现此目的的有效技术?还是等待发生的灾难?我想编辑根本问题以澄清这一点,以帮助下一个人。谢谢!
  • 哦,没有意识到我需要标记@ikegami
  • @Bruce Miller,(这是您要评论的我的答案,您不需要在这里这样做。但早些时候,这是您的问题,所以您需要这样做。)哦当然,你所做的绝对没有错(尽管use Foo::Version; our $VERSION = $Foo::Version::VERSION; 会更简单一些)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-30
  • 1970-01-01
  • 2014-06-03
  • 2011-08-18
  • 1970-01-01
  • 1970-01-01
  • 2014-03-10
相关资源
最近更新 更多