12

从 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 - 识别骆驼书中描述的 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)下运行?

请尽可能包括参考资料和代码示例。

4

5 回答 5

14

最大的故意不兼容之一是数组插值,它在 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。因为多重性正在模拟一个单独的过程,所以默认情况下不共享任何数据。只有您所说的共享数据是共享的。这使得它们使用起来更加安全,尽管 ithread 需要很长时间才能稳定。像 Elizabeth Mattijsen 和 Jerry Hedden 这样的人做到了这一点。

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

另一个大的不兼容来自 5.6 和 5.8 之间的 Unicode。5.6 中的 Unicode 自爆。字符串是否为 Unicode 由周围的范围决定。它在 5.8 中完全重新设计,所以现在字符串的 Unicodeiness 与字符串相关联。使用 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 修复了它。

于 2009-12-06T21:33:26.180 回答
12

伪散列是我最近想到的一个例子。通常,perldelta 文件概述了特定版本中的不兼容更改。这些变化几乎总是模糊不清(如伪散列)或很小。

于 2009-12-06T14:28:43.713 回答
11

是的。有很多,尽管它们通常很小。有时这是由于弃用周期最终以删除结束。有时这是由于新(和实验性)功能的语义发生了变化。有时它是对无法正常工作的事情的错误修复。Perl 开发人员尽可能地保持版本之间的向后兼容性。我不记得曾经有一个脚本因升级到新版本的 Perl 而被破坏。

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

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

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

于 2009-12-06T14:29:47.690 回答
5

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

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

没错,23。为什么?因为“关联数组”不是 Perl 1 中的一流对象。 $foo{bar}工作但没有%foo. 我真的不知道为什么,即使 Perl 1 手册页也承认这是有缺陷的。因此,为了与 Perl 1 兼容,您可以在不使用 的情况下访问全局哈希%,可能是您的键盘坏了或 Apple 决定没有人使用该%符号。

chdir有一些奇怪的地方。 chdir()没有参数将带你到你的主目录,复制 shellcd行为。不幸的是,这样会chdir undef导致chdir ""很难发现周围的错误chdir。幸运的是,这种行为已被弃用。我必须确保它在 5.14 中消失。

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

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

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

于 2009-12-07T02:15:27.193 回答
3

我在 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 之间的常见问题解答。

于 2009-12-10T17:12:08.577 回答