从 Perl 1.0 首次公开发布(1987 年 12 月 18 日)到当前稳定版本 5.10.1(2009 年)已经过去了 22 年。

在这 22 年里,发布了以下值得注意的版本:

  • Perl 1.0(1987 年 - 初始版本)
  • Perl 2(1988 - 更好的正则表达式)
  • Perl 3(1989 - 支持二进制数据流)
  • Perl 4(1991 - 识别 Camel Book 中描述的 Perl 版本)
  • Perl 5(1994 年 - 引入了重大更改,几乎完全重写了解释器)
  • Perl 5.6(2000 - 64 位支持、unicode 字符串、大文件支持)
  • Perl 5.8(2002 - 改进的 unicode 支持,新的 IO 实现)
  • Perl 5.10(2007 - 新的 switch 语句、正则表达式更新、智能匹配运算符)

我正在寻找 Perl 历史上向后不兼容的具体例子。

问题:

  • 在 Perl 22 年的历史中,是否有任何 Perl 向后不兼容的例子,即针对 Perl 版本 X 的 Perl 源代码无法在版本 Y 下运行(其中 Y > X)?

请尽可能包含参考文献和代码示例。

有帮助吗?

解决方案

最大的故意不兼容性之一是数组插值,它在 Perl 4 和 Perl 5 之间发生了变化。

my @example = qw(1 2 3);
print "foo@example.com";

在 Perl 4 中,这将是:

foo@example.com

在 Perl 5 中,这将是:

foo1 2 3.com

幸运的是,如果数组不存在,Perl 会警告您“可能发生意外插值”。

线程在 5.005 和 5.6 之间经历了很大的变化。“5005 个线程”使用传统的 POSIX 线程模型,其中所有全局数据都是共享的。虽然理论上这更快,因为那时 Perl 只能使用 POSIX 线程,但这对 Perl 编码人员来说是一场噩梦。大多数 Perl 模块都不是线程安全的。而且它从来没有真正发挥过作用。

在5.6中,ActiveState等人在Windows上制作了fork()。当您在 Windows 上 fork() 时,Perl 会复制解释器对象并运行两个解释器的操作码。这被称为“多重性”。

在 5.8 中,Arthur Bergman 运行了它并用它来创建 ithread。由于多重性正在模拟一个单独的进程,因此默认情况下不会共享任何数据。只有您所说共享的数据才会被共享。这使得它们使用起来更加安全,尽管 ithreads 花了很长时间才稳定下来。伊丽莎白·马泰森 (Elizabeth Mattijsen) 和杰里·赫登 (Jerry Hedden) 等人让这一切成为现实。

5005个线程最终在5.10.0中被删除。存在兼容性层,但我怀疑它是否真的可以在生产代码中工作。

另一个很大的不兼容性是 5.6 和 5.8 之间的 Unicode。5.6 中的 Unicode 爆发了。字符串是否是 Unicode 由周围的范围决定。它在 5.8 中被完全重新设计,因此现在字符串的 Unicode 性与字符串相关联。使用 5.6 的 Unicode 编写的代码通常必须在 5.8 中重写,通常是因为要使 5.6 的 Unicode 正常工作,您必须进行丑陋的 hack。

最近,5.10.1 对智能匹配进行了一系列不兼容的更改。幸运的是,它们是在 5.10.0 中引入的,所以这没什么大不了的。故事是 Perl 6 引入了智能匹配概念,并将其向后移植到 Perl 5 的开发版本。随着时间的推移,Perl 6 的智能匹配理念发生了变化。没有人告诉 Perl 5 的人,它在 5.10.0 中没有改变。 拉里·沃尔注意到了,并做了相当于天哪,你做错了! 新的 Perl 6 版本被认为明显更好,因此 5.10.1 修复了它。

其他提示

伪哈希 这是我最近想到的一个例子。一般来说, perldelta 文件 了解特定版本中不兼容更改的概述。这些变化几乎总是晦涩难懂(如伪哈希)或很小。

是的。有很多,尽管它们通常都很小。有时这是由于弃用周期最终以删除而告终。有时这是由于新的(和实验性的)功能的语义改变所致。有时,它会修复无法正常工作的问题。Perl 开发人员竭尽全力尽可能地保持版本之间的向后兼容性。我不记得曾经有过因为升级到新版本的 Perl 而被破坏的脚本。

内部哈希顺序已更改多次。虽然这不是您应该依赖的东西,但如果您无意中这样做,它可能会导致问题。

主要 (5.x) 版本之间的二进制不兼容性很常见,但这通常仅意味着任何 XS 扩展都需要重新编译。

完整的列表太长,无法在此列出。您可以通过检查每个版本的“不兼容的更改”部分来获取它 历史.

OTOH,有一些可追溯到 Perl 1 的狂野功能仍然有效。例如,这打印了什么?

%foo = (foo => 23);
print values foo

没错,23。为什么?因为“关联数组”在 Perl 1 中不是一流的对象。 $foo{bar} 有效,但没有 %foo. 。我真的不知道为什么,甚至 Perl 1 手册页也承认这是疣。因此,为了与 Perl 1 兼容,您可以访问全局哈希,而无需使用 %, ,也许如果你的键盘坏了或者苹果决定没有人使用 % 象征。

chdir 有一些奇怪的地方。 chdir() 不带任何参数将带您进入主目录,复制 shell cd 行为。不幸的是,也会如此 chdir undefchdir "" 使得很难发现周围的错误 chdir. 。幸运的是,这种行为已被弃用。我必须确保它在 5.14 中消失。

$[ 仍然存在并且未被弃用,但“非常不鼓励”。它改变了数组的第一个索引,所以如果你是像我一样的人并且从 1 开始计数,你可以这样做:

$[ = 1;
@foo = qw(foo bar baz);
print $foo[2];   # prints bar

Perl 5 将其更改为文件范围,否则它会拖累性能,并且是 CrAzY 的重要来源。

我在使用 Perl4 和 Perl5 以不同的顺序评估作业的左侧和右侧时遇到了一些奇怪的错误,引用了 Perl 给粗心的人带来陷阱:

LHS 对比任何赋值运算符的 RHS。LHS 在 perl4 中首先评估,在 perl5 中其次评估;这会影响子表达式中副作用之间的关系。

@arr = ( 'left', 'right' );
$a{shift @arr} = shift @arr;
print join( ' ', keys %a );
# perl4 prints: left
# perl5 prints: right

对于一些新的和可能不兼容的东西,请参阅 常见问题解答 介于 Perl4 和 Perl5 之间。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top