Perl 版本中向后不兼容的一些具体示例有哪些?
-
13-09-2019 - |
题
从 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 undef
和 chdir ""
使得很难发现周围的错误 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 之间。