我的所有 perl 模块 .pm 文件都需要 `$VERSION` 定义吗?

KJ7*_*LNW 7 perl cpan version

我刚刚向PDL::IO::Touchstone发行版添加了一个新文件,并注意到 CPAN 的索引器显示版本为 undef,因为$VERSION缺少:

     module : PDL::IO::MDIF
     version: undef
     in file: PDL-IO-Touchstone-1.009/lib/PDL/IO/MDIF.pm
     status : indexed
Run Code Online (Sandbox Code Playgroud)

所以 ::MDIF 没有$VERSION,但实际上它与 Makefile.PL 中注明的发行版相同:

     module : PDL::IO::MDIF
     version: undef
     in file: PDL-IO-Touchstone-1.009/lib/PDL/IO/MDIF.pm
     status : indexed
Run Code Online (Sandbox Code Playgroud)

问题:

  • 那么发行版中的这个模块需要一个版本吗?
  • 如果是这样,新模块是否应该与in提供的模块$VERSION分开维护? $VERSIONVERSION_FROMMakefile.PL
    • 我可以做$VERSION = $PDL::IO::Touchstone::VERSION,但不确定 CPAN 是否会解决这个问题。会吗?

我环顾四周,发现了很多关于版本控制实践的讨论,但没有任何关于同一 Perl 发行包中模块版本的讨论。请分享这里的最佳实践应该是什么,我是 Perl 模块的新手,这是我推出的第一个 2 文件发行版。

我确信在发布新的 dist 时我会更新主文件,但不确定当 dist 中其他模块发生更改时我是否会记得更改它们的版本。如果这里有一个低维护选项,那就太好了。

更新

我尝试了下面一些答案中的建议。这些都不起作用:

  • $VERSION = do { use PDL::IO::Touchstone; $PDL::IO::Touchstone::VERSION };

  • use PDL::IO::Touchstone; our $VERSION = $PDL::IO::Touchstone::VERSION;

这是 github 上的 MDIF.pm 文件:https://github.com/KJ7LNW/perl-PDL-IO-Touchstone/blob/master/lib/PDL/IO/MDIF.pm#L22

CPAN 仍然显示version: undef

Status: Version parsing problem
===============================

     module : PDL::IO::MDIF
     version: undef
...
Run Code Online (Sandbox Code Playgroud)

好吧,那么谁会得到复选标记......还有其他想法吗?

bri*_*foy 6

我喜欢提供我所有模块的版本。这不是一个要求,但要考虑当用户对 CPAN 的工作原理一无所知或知之甚少时尝试升级时的体验。ikegami 已经为此给出了 tl;dr

当您想要从 CPAN 更新模块时,该工具会查看该模块的$VERSION(以及VERSION子模块)。如果该模块没有版本,则为 undef。当 CPAN.pm(或其他工具可能)查看是否有更新的版本时,它没有找到它认为更新的版本,因为最新版本也是 undef。

一个具体的例子是Mojo::UserAgent。Mojolicious 仅版本主模块。其他模块没有版本。我通常会做很多 Web 客户端的工作,所以我的工作产品并不关心 Mojo 的 Web 服务器端。使用我的一些东西的人可能甚至不知道除了客户端的东西之外还有 Mojo 的不同部分(他们甚至可能知道 Perl)。

如果我运行cpan Mojo::UserAgent,它会将我当前安装的版本 (undef) 与 CPAN 上的最新版本 (undef) 进行比较。这意味着 CPAN.pm 猜测我没有早于最新可用版本的内容。

$ cpan -D Mojo::UserAgent
Mojo::UserAgent
-------------------------------------------------------------------------
    (no description)
    S/SR/SRI/Mojolicious-9.28.tar.gz
    /usr/local/perls/perl-5.36.0/lib/site_perl/5.36.0/Mojo/UserAgent.pm
    Installed: undef
    CPAN:      undef  up to date
    Sebastian Riedel (SRI)
    kraihx@googlemail.com
Run Code Online (Sandbox Code Playgroud)

现在,我知道这个发行版可以做到这一点。但仅仅使用我写的东西的人Mojo::UserAgent可能不会。如果他们需要 Mojolicious 8 来获取特定的 CSS 选择器,那么他们怎么知道呢?

通常,您可以指定模块的最低版本:

use File::Glob 8.0;
Run Code Online (Sandbox Code Playgroud)

我不能要求最低版本Mojo::UserAgent

use Mojo::Usergent 8.0;
Run Code Online (Sandbox Code Playgroud)

我收到一个奇怪的错误(还有其他导入问题和设计决策):

Can't locate 8.pm in @INC (@INC contains: ...)
Run Code Online (Sandbox Code Playgroud)

这不是什么大问题,因为 Mojolicious 大部分是独立的,所以我可以指定它的最低版本:

use Mojolicious 8.0;
Run Code Online (Sandbox Code Playgroud)

但是,我必须知道所有这些是如何工作的,发行版是如何工作的,以及 Perl 是如何做到这一点的。对于我的东西的临时用户来说,他们只是想开始工作,包括修改我所做的事情,他们必须发现一些知识才能知道这一点。他们必须知道 CPAN.pm 或 PAUSE 如何决定最新版本是什么,等等。

此外,对于发行版中的模块来说,这是一个问题,这些模块不会更改并且没有逻辑原因进行版本升级。嗯,它们这样做是因为它们对有版本的主模块有隐式依赖,但我们不习惯声明该版本。例如,考虑某个与已更改的 API 一起使用的模块,但更改的主要内容是在它使用的另一个模块中。你直接使用的模块并没有改变它的字面文本,但它不能按原样工作,因为世界不同了。但是,由于该文件中的文字文本并未更改,因此我们通常不会更改版本。

也许我们应该声明主模块依赖关系,但这需要大量工作。它给文件添加了一些看似无端的改动,这在回购历史中很烦人。啊,天哪,既然我已经想到了这一点,我需要在一些发行版中修复这个问题。一些——不是全部。我不知道。值得思考的事情。

当然,我可以在发行版、脚本或其他任何内容中记录所有这些。但我们知道我可以说出来,他们也可以读到它,但仍然没有意识到它的重要性。而且,此时我们距离“只是工作”还很遥远。

  • 执行 `our $VERSION = do { use PDL::IO::Touchstone; 不过,在一行上 $PDL::IO::Touchstone::VERSION };` 是一个更好的解决方案,因为索引器仅评估设置 $VERSION 的行。 (4认同)

ike*_*ami 5

CPAN 仅需要一个分发版本,并且您已使用VERSION_FROM.

有多种做法。

  • 只有“主模块”有版本。
  • 每个文件都有自己的版本。
  • 每个文件共享发行版的版本。

CPAN 评估设置 $VERSION 的行,因此如果全部都在一行上,则以下内容应该有效:

use PDL::IO::Touchstone; $VERSION = $PDL::IO::Touchstone::VERSION;
Run Code Online (Sandbox Code Playgroud)