如何编写CPAN模块以支持多个Perl版本?

Pet*_*ini 6 perl cpan

假设我在CPAN上有一个模块,我想升级它以使用更新的Perls中的功能.现在,正如我所理解的那样,如果我这样做,我会在这个版本的沙子中说一句,如果你有Perl的X版本,你只能使用我的模块.

是否有一种干净/规范的方式来支持CPAN上同一模块的两个不同分支?

即,2.x系列将继续维持版本回到5.8.x,而3.x将用于版本5.16+.

Bor*_*din 5

该$]变量已被弃用,以支持将当前Perl解释器的版本保存为对象的$^V变量version(或者undef如果版本早于v5.6).

这允许版本进行比较,以一个版本字符串常量等v5.10产生的填充字符串(包含每个版本序号为字符代码,所以v5.10 eq "\x05\x0A"是真).

由于V-字符串是字符串,你必须将它们与字符串比较比较lt,le,eq,ge和gt,所以你会喜欢写东西

use v5.6;

if ( $^V ge v5.10 ) { ... }
Run Code Online (Sandbox Code Playgroud)

但我想知道你的代码如何在不同版本的Perl之间进行更新?大多数变化都是语法变化,只是提供了编写某些结构的更好方法.通常只需要为您想要支持的最早版本编写代码.曾经是v5.8,但v5.10是一个重大修订版,许多人认为它现在已经超过七年了.

  • Re"因为v-strings是字符串,你必须将它们与字符串比较器进行比较",不是这样.实际上,版本对象文档中的所有示例都使用数字比较运算符.字符串比较运算符也可以工作,但绝对不需要使用它们.("版本对象重载了`cmp`和`<=>`运算符.Perl基于这两个运算符自动生成所有其他比较运算符,因此所有正常的逻辑比较都可以.") (3认同)
  • `$]`实际上并没有被弃用.这是一个文档错误,此后已经[修复](http://perl5.git.perl.org/perl.git/commitdiff/4ad0ecd4c5a81ed8f71804b908656dca23f4867e). (3认同)

ike*_*ami 4

拥有两个同名分支的问题是,cpan The::Module对于某些用户来说,这会不必要地失败(因为它将始终获得最新版本)。他们仍然可以安装旧版本的模块,但会麻烦得多。相反,将模块更改为

package The::Module;
do($] < 5.016 ? 'The/Module/Pre5016.pm' : 'The/Module/5016.pm')
   or die $@ || $!;
1;
Run Code Online (Sandbox Code Playgroud)

如果只有模块的有限部分不同,您可以简单地使用

sub _foo_compatible { ... }

sub _foo_fast { ... }

*foo = $] < 5.016 ? \&_foo_compatible : \&_foo_fast;
Run Code Online (Sandbox Code Playgroud)

第二种方法的缺点是需要在 5.8 中编译两个子程序(除非您添加eval EXPR到混合中)。

  • @Borodin,这是一个文档错误。`$]` 从未被弃用,并且不再被标记为已弃用。 (2认同)