perl5160delta - perl v5.16.0 的新增功能
本文档描述了 5.14.0 版本和 5.16.0 版本之间的差异。
如果您要从 5.12.0 等早期版本升级,请先阅读 perl5140delta,其中描述了 5.12.0 和 5.14.0 之间的差异。
此版本中的一些错误修复已移植到 5.14.x 的后续版本中。这些修复在括号中用 5.14.x 版本表示。
随着 Perl 5.16.0 的发布,5.12.x 版本系列现在已超出其支持期限。将来可能会有 5.12.x 版本发布,但仅在出现严重的安全问题时才会发布。使用 Perl 5.12 或更早版本的用户应考虑升级到更新的 Perl 版本。
此策略在 perlpolicy 中有更详细的描述。
use VERSION
从本版本开始,像 use v5.16
这样的版本声明现在会先禁用所有功能,然后再启用新的功能包。这意味着以下内容是正确的
use 5.016;
# only 5.16 features enabled here
use 5.014;
# only 5.14 features enabled here (not 5.16)
use v5.12
及更高版本继续启用 strict,但显式的 use strict
和 no strict
现在会覆盖版本声明,即使它们出现在前面
no strict;
use 5.012;
# no strict here
有一个新的 ":default" 功能包,它代表在任何版本声明或 use feature
被看到之前启用的功能集。低于 5.10 的版本声明现在启用 ":default" 功能集。这实际上不会改变 use v5.8
的行为,因为添加到 ":default" 集中的功能是那些传统上默认启用的功能,在它们可以被关闭之前。
no feature
现在重置为默认功能集。要禁用所有功能(这可能是一个非常特殊的请求,因为它可能不匹配任何命名的语义集),你现在可以写 no feature ':all'
。
$[
现在在 use v5.16
下被禁用。它是默认功能集的一部分,可以通过 use feature 'array_base'
显式地打开或关闭。
__SUB__
新的 __SUB__
标记,在 current_sub
功能(参见 feature)或 use v5.16
下可用,返回对当前子例程的引用,使编写递归闭包更容易。
eval
eval
运算符有时将字符串参数视为字符序列,有时视为字节序列,具体取决于内部编码。内部编码不应该有任何区别,但有一些代码依赖于这种不一致。
新的 unicode_eval
和 evalbytes
特性(在 use 5.16.0
下启用)解决了这个问题。unicode_eval
特性使 eval $string
始终将字符串视为 Unicode。evalbytes
特性提供了一个名为 evalbytes
的函数,它始终将参数评估为字节字符串。
这些特性还修复了源过滤器泄漏到外部动态作用域的奇特现象。
有关更多详细信息,请参阅 feature。
substr
左值改造当 substr
在左值或潜在左值上下文中使用两个或三个参数调用时,将返回一个特殊的左值标量,它在赋值时会修改原始字符串(第一个参数)。
以前,传递给 substr
的偏移量(第二个和第三个参数)会立即转换为与字符串匹配,负偏移量会转换为正偏移量,超出字符串末尾的偏移量会被截断。
现在,偏移量在返回的特殊左值标量中被记录下来,没有修改,substr
本身甚至不会查看原始字符串,而是在读取或修改返回的左值时才会查看。
这些更改导致了不兼容的更改
如果原始字符串在调用 substr
后但在赋值给其返回值之前改变了长度,负偏移量将记住它们在字符串末尾的位置,影响如下代码
my $string = "string";
my $lvalue = \substr $string, -4, 2;
print $$lvalue, "\n"; # prints "ri"
$string = "bailing twine";
print $$lvalue, "\n"; # prints "wi"; used to print "il"
省略第三个参数也会发生同样的情况。返回的左值将始终扩展到字符串的末尾,即使字符串变得更长。
由于此更改还允许修复许多错误(请参阅 "substr
运算符"),并且由于负偏移量的行为从未被指定,因此该更改被认为是可以接受的。
tied
的返回值tied
在绑定变量上返回的值现在是实际保存绑定变量所绑定对象的标量。这使得可以使用 Scalar::Util::weaken(tied $tied_variable)
来削弱绑定。
除了添加全新的脚本和现有脚本中的新字符外,这个新版本的 Unicode,一如既往地对现有字符进行了一些更改。其中一项可能会影响某些应用程序的更改是,Latin-1 范围内的两个字符 PILCROW SIGN 和 SECTION SIGN 的通用类别已从 Other_Symbol 更改为 Other_Punctuation。藏文、埃塞俄比亚语和爱琴海语中的每个字符都进行了相同的更改。代码点 U+3248..U+324F(黑色方块上的圆圈数字十到黑色方块上的圆圈数字八十)的通用类别已从 Other_Symbol 更改为 Other_Numeric。换行属性对希伯来语和日语进行了更改;由于 6.1 中的其他更改,Perl 正则表达式构造 \X
现在对泰语和老挝语中的一些字符的工作方式有所不同。
已为许多属性值定义了新的别名(同义词);这些别名与之前存在的别名一起,都已在 perluniprops 中进行交叉索引。
charnames::viacode()
的返回值会受到其他更改的影响
Code point Old Name New Name
U+000A LINE FEED (LF) LINE FEED
U+000C FORM FEED (FF) FORM FEED
U+000D CARRIAGE RETURN (CR) CARRIAGE RETURN
U+0085 NEXT LINE (NEL) NEXT LINE
U+008E SINGLE-SHIFT 2 SINGLE-SHIFT-2
U+008F SINGLE-SHIFT 3 SINGLE-SHIFT-3
U+0091 PRIVATE USE 1 PRIVATE USE-1
U+0092 PRIVATE USE 2 PRIVATE USE-2
U+2118 SCRIPT CAPITAL P WEIERSTRASS ELLIPTIC FUNCTION
Perl 将接受所有这些名称作为输入,但 charnames::viacode()
现在返回每对的新名称。对于 U+2118 的更改被 Unicode 认为是更正,即原始名称是错误的(但同样,使用它来引用 U+2118 将永远有效)。但这些更改中的大多数是 Unicode 6.0 在命名日本手机中使用的字符为“BELL”时所犯错误的后续影响,这与该名称在行业中的长期使用(以及 Unicode 建议使用该名称)相冲突,即指代 U+0007 处的 ASCII 控制字符。因此,该名称在 Perl v5.14 之后已弃用,任何使用它都会引发警告消息(除非关闭)。“ALERT”现在是此代码点的首选名称,“BEL”是可接受的简短形式。对于新手机字符的名称,其代码点为 U+1F514,在此版本的 Perl 中仍未定义(因此我们没有完全实现 Unicode 6.1),但从 v5.18 开始,BELL 将指代此字符,而不是 U+0007。
Unicode 已经采取措施确保此类错误不再发生。该标准现在包含所有普遍接受的控制字符名称和缩写,而以前没有(尽管大多数控制字符都有推荐名称,Perl 使用了这些名称)。这意味着大多数这些推荐名称现在已正式包含在标准中。Unicode 没有为上面列出的 U+008E 和 U+008F 之间的四个代码点推荐名称,在标准化这些代码点时,Unicode 微妙地改变了 Perl 之前为它们提供的名称,将每个名称末尾的空格替换为连字符。Unicode 还正式接受 Perl 已弃用的名称,例如 FILE SEPARATOR。现在唯一弃用的名称是 BELL。最后,Perl 现在使用新的官方名称,而不是旧的(现在被认为已过时)名称,用于上面列表中的前四个代码点(包含括号的代码点)。
现在名称已包含在 Unicode 标准中,此类更改应该不会再发生,尽管仍然可能进行更正,例如针对 U+2118 的更正。
Unicode 还添加了一些名称缩写,Perl 现在接受这些缩写:SP 代表 SPACE;TAB 代表 CHARACTER TABULATION;NEW LINE、END OF LINE、NL 和 EOL 代表 LINE FEED;LOCKING-SHIFT ONE 代表 SHIFT OUT;LOCKING-SHIFT ZERO 代表 SHIFT IN;ZWNBSP 代表 ZERO WIDTH NO-BREAK SPACE。
有关此版本的 Unicode 的更多详细信息,请参阅 http://www.unicode.org/versions/Unicode6.1.0/。
use charnames
不再需要用于 \N{name}
当遇到 \N{name}
时,charnames
模块现在会在需要时自动加载,就像指定了 :full
和 :short
选项一样。有关更多信息,请参阅 charnames。
\N{...}
现在可以进行 Unicode 松散名称匹配这在下面 "更新的模块和语义" 中的 charnames
项目中进行了描述。
Perl 现在对 Unicode 符号名称提供了适当的支持。以前,*{$foo}
会忽略内部 UTF8 标志,并使用底层表示的字节来查找符号。这意味着 *{"\x{100}"}
和 *{"\xc4\x80"}
会返回相同的值。Perl 的所有这些部分都已修复,以考虑 Unicode
方法名称(包括传递给 use overload
的名称)
类型全局名称(包括变量、子程序和文件句柄的名称)
包名
goto
符号解引用
bless()
和 tie()
的第二个参数
ref()
的返回值
子程序原型
属性
各种提及变量名或值、方法等的警告和错误消息。
此外,已修复一个解析错误,该错误阻止了 *{é}
隐式引用名称,而是将其解释为 *{+é}
,这会导致严格违规。
*{"*a::b"}
会自动剥离 *,如果它后面跟着一个 ASCII 字母。这已扩展到所有 Unicode 标识符字符。
现在,单个字符的非 ASCII 非标点符号变量(如 $é
)会受到“仅使用一次”警告。它们以前是豁免的,因为它们被视为标点符号变量。
此外,现在支持单个字符的 Unicode 标点符号变量(如 $‰
)[perl #69032]。
use locale
中添加了一个可选参数
use locale ':not_characters';
它告诉 Perl 使用当前区域设置的所有部分,除了 LC_CTYPE
和 LC_COLLATE
部分。相反,字符集被假定为 Unicode。这允许无缝地混合区域设置和 Unicode,包括越来越多的 UTF-8 区域设置。当使用这种混合形式的区域设置时,open pragma 的 :locale
层可用于与文件系统交互,并且有可用于 ARGV 和环境变量转换的 CPAN 模块。
完整详细信息请参见 perllocale。
fc
和相应的转义序列 \F
用于 Unicode 折叠大小写Unicode 折叠大小写是对小写的扩展,在不区分大小写地比较两个字符串时会产生更好的结果。它长期以来一直用于正则表达式 /i
匹配中的内部。现在可以通过新的 fc
函数调用(通过 "use feature 'fc'"
或 use v5.16
启用,或通过 CORE::fc
显式调用)或通过双引号字符串中的新 \F
序列显式使用。
完整详细信息请参见 "fc" in perlfunc。
Script_Extensions
属性。这是 Unicode 6.0 中的新增功能,它是 Script
属性的改进版本。详细信息请参见 "Scripts" in perlunicode。
大多数 XS 作者都知道 T_AVREF (AV*
)、T_HVREF (HV*
)、T_CVREF (CV*
) 和 T_SVREF (SVREF
或 \$foo
) 的 OUTPUT 类型映射中存在一个长期存在的错误,该错误要求手动递减返回值的引用计数,而不是类型映射来处理此问题。为了向后兼容,这无法在默认类型映射中更改。但我们现在提供了额外的类型映射 T_AVREF_REFCOUNT_FIXED
等,它们没有表现出此错误。在您的扩展中使用它们就像在您的 TYPEMAP
部分中有一行代码一样简单
HV* T_HVREF_REFCOUNT_FIXED
is_utf8_char()
当遇到格式错误的 UTF-8 输入时,XS 可调用函数 is_utf8_char()
可以读取字符串末尾最多 12 个字节。这无法在不更改其 API 的情况下修复,因此现在不建议使用它。请改用 is_utf8_char_buf()
(如下所述)。
is_utf8_char_buf()
此函数旨在替换已弃用的 "is_utf8_char()" 函数。它包含一个额外的参数以确保它不会读取输入缓冲区的末尾。
is_utf8_foo()
函数,以及 utf8_to_foo()
等大多数其他接受 UTF-8 编码输入的 XS 可调用函数隐式假设 UTF-8 相对于缓冲区长度是有效的(没有格式错误)。不要在没有首先确保它是有效的 UTF-8 的情况下执行诸如更改字符的大小写或查看它是否为字母数字之类的操作。这可以通过使用以下函数之一来安全地对整个字符串执行:is_utf8_string()
、is_utf8_string_loc()
和 is_utf8_string_loclen()
。
许多新函数已添加到用于操作词法垫的 API 中。有关更多信息,请参阅 "perlapi 中的 Pad 数据结构"。
$$
可以被赋值$$
在 Perl 5.8.0 中被设为只读。但只是有时:local $$
会使其再次可写。一些 CPAN 模块正在使用 local $$
或 XS 代码来绕过只读检查,因此没有理由将 $$
保持为只读。(此更改还允许在保持向后兼容性的同时修复一个错误。)
$^X
在 FreeBSD、OS X 和 Solaris 上转换为绝对路径$^X
现在在 OS X、FreeBSD(无需挂载 /proc)和 Solaris 10 及 11 上被转换为绝对路径。这增强了之前在 Linux、FreeBSD 和 NetBSD 上使用 /proc 的方法(在所有情况下,如果已挂载)。
这使得可重定位的 Perl 安装在这些平台上更加有用。(参见 INSTALL 中的“可重定位的 @INC”)
当前 Perl 的 feature 包现在已在交互式调试器中输入的命令中启用。
调试器中的 t 命令(切换跟踪模式)现在接受一个数字参数,该参数确定要跟踪的子例程调用级别。
enable
和 disable
调试器现在具有 disable
和 enable
命令,用于禁用现有断点并重新启用它们。参见 perldebug。
调试器的“b”命令用于设置断点,现在允许行号以文件名作为前缀。参见 "b [file]:[line] [condition]" in perldebug。
CORE
命名空间CORE::
前缀CORE::
前缀现在可以在 feature.pm 启用的关键字上使用,即使在 use feature
的作用域之外。
CORE
命名空间中的子例程许多 Perl 关键字现在在 CORE 命名空间中可用作子例程。这使它们可以被别名化
BEGIN { *entangle = \&CORE::tie }
entangle $variable, $package, @args;
以及绕过原型
sub mytie(\[%$*@]$@) {
my ($ref, $pack, @args) = @_;
... do something ...
goto &CORE::tie;
}
其中一些不能通过引用或通过 &foo
语法调用,而必须作为裸词调用。
有关详细信息,请参见 CORE。
当无法确定变量名时,自动生成的句柄现在命名为 __ANONIO__,而不是 $__ANONIO__。
现在可以自动加载自定义排序子例程 [perl #30661]
sub AUTOLOAD { ... }
@sorted = sort foo @list; # uses AUTOLOAD
continue
不再需要 "switch" 特性continue
关键字有两个含义。它可以在循环后引入一个 continue
块,也可以退出当前的 when
块。到目前为止,后一种含义仅在启用 "switch" 特性时才有效,否则将是语法错误。由于 feature.pm 的主要目的是避免与用户定义的子例程发生冲突,因此 continue
没有理由依赖它。
当解释器的阶段发生变化时,phase-change
探针将触发,它跟踪 ${^GLOBAL_PHASE}
变量。arg0
是新的阶段名称;arg1
是旧的阶段名称。这对于将您的检测限制在以下一个或多个阶段很有用:编译时、运行时或析构时。
__FILE__()
语法__FILE__
、__LINE__
和 __PACKAGE__
标记现在可以在它们后面写一对空括号。这使得它们解析方式与 time
、fork
和其他内置函数相同。
\$
原型接受任何标量左值\$
和 \[$]
子例程原型现在接受任何标量左值参数。以前它们只接受以 $
开头的标量以及哈希和数组元素。此更改使它们与内置 read
和 recv
函数(以及其他函数)解析其参数的方式保持一致。这意味着可以将自定义子例程覆盖内置函数,这些子例程以相同的方式解析其参数。
_
子例程原型中的 _
字符现在允许在 @
或 %
之前。
is_utf8_char_buf()
而不是 is_utf8_char()
后者现在已被弃用,因为它的 API 不足以保证它不会读取(最坏情况下最多 12 个字节)超出其输入字符串的末尾。请参阅 is_utf8_char_buf()。
现在提供了两个新的 XS 可访问函数 utf8_to_uvchr_buf()
和 utf8_to_uvuni_buf()
来防止这种情况,并且 Perl 核心已转换为使用它们。请参阅 "内部更改"。
File::Glob::bsd_glob()
使用 GLOB_ALTDIRFUNC 时的内存错误 (CVE-2011-2728)。使用不支持的标志 GLOB_ALTDIRFUNC 调用 File::Glob::bsd_glob
会导致访问冲突/段错误。接受来自外部来源的标志值的 Perl 程序可能会使自己暴露于拒绝服务或任意代码执行攻击。目前没有已知的漏洞。通过明确禁用所有不支持的标志并将未使用的函数指针设置为 null 来解决此问题。由 Clément Lecigne 报告的错误。(5.14.2)
$(
时正确设置权限一个假设的错误(在实践中可能无法利用),因为在设置 $(
时有效组 ID 设置不正确已被修复。该错误只会影响具有 setresgid()
但没有 setregid()
的系统,但据知不存在此类系统。
现在直接读取 Unicode 数据库文件已被弃用。这些文件存储在 lib/unicore 目录中。相反,您应该使用 Unicode::UCD 中的新函数。这些函数提供稳定的 API,并提供完整的信息。
Perl 可能会在将来的某个时间点更改或删除这些文件。应用程序最有可能使用的文件是 lib/unicore/ToDigit.pl。可以使用 "Unicode::UCD 中的 prop_invmap()" 来获取其数据。
is_utf8_char()
、utf8_to_uvchr()
和 utf8_to_uvuni()
此函数已弃用,因为它可能会读取输入字符串的末尾。请使用新的 is_utf8_char_buf()、utf8_to_uvchr_buf()
和 utf8_to_uvuni_buf()
代替。
本节作为对可能在下一个 Perl 版本 (5.18.0) 中被移除或 弃用 的功能的通知。如果您的代码依赖于这些功能,您应该通过 邮件列表 或 perlbug 联系 Perl 5 维护者,解释您的用例并告知弃用流程。
这些模块可能会被标记为 从核心 中弃用。这仅仅意味着它们将不再默认安装在核心发行版中,但仍将在 CPAN 上可用。
CPANPLUS
Filter::Simple
PerlIO::mmap
Pod::LaTeX
Pod::Parser
SelfLoader
Text::Soundex
Thread.pm
这些平台的特殊构建支持可能会在 5.17.0 开发系列中被移除。
BeOS
djgpp
dgux
EPOC
MPE/iX
Rhapsody
UTS
VM/ESA
交换 $< 和 $>
有关此未来弃用的更多信息,请参阅 相关的 RT 票证。
sfio、stdio
Perl 支持在没有 PerlIO 的情况下构建,而是使用 stdio 或 sfio 包装器。这种 Perl 构建不支持 IO 层,因此不支持 Unicode IO,这使得它相当受限。
如果需要使用 stdio,PerlIO 支持 stdio
层,类似地,可以生成 sfio 层。
正则表达式中未转义的字面量 "{"
。
从 v5.20 开始,计划要求字面量 "{"
被转义,例如,在它前面加上反斜杠。在 v5.18 中,将为所有此类用法发出弃用警告消息。这仅影响匹配字面量 "{"
的模式。此字符的其他用法,例如作为量词或序列的一部分,如以下用法,完全不受影响。
/foo{3,5}/
/\p{Alphabetic}/
/\N{DIGIT ZERO}
移除此功能将允许扩展 Perl 的模式语法,并为现有语法提供更好的错误检查。有关示例,请参阅 perlre 中的“量词”。
当与其他转义符结合使用时,双引号字符串中"\Q"
语义的改造。
在\Q...\E
对中,\Q
与\x
、\L
等转义符的组合存在一些错误和不一致。这些需要修复,这样做必然会改变当前的行为。更改尚未确定。
特殊块(BEGIN
、CHECK
、INIT
、UNITCHECK
、END
)现在在空上下文调用。这避免了对最后一个语句结果的浪费复制 [perl #108794]。
overloading
编译指示和正则表达式对象使用no overloading
,qr//
返回的正则表达式对象现在被字符串化为 "Regexp=REGEXP(0xbe600d)" 而不是正则表达式本身 [perl #108780]。
两个可能未使用的 XS 类型映射条目已从核心类型映射中移除:T_DATAUNIT 和 T_CALLBACK。如果您是这些条目的用户(这不太可能),请参阅 perlxstypemap 中关于如何恢复它们的说明。
这些在上面 "支持(几乎)Unicode 6.1" 中有详细说明。您可以编译此版本的 Perl 以使用 Unicode 6.0。请参阅 "在 perlunicode 中的“为非常严肃的黑客准备的,将 Perl 改造成在早期 Unicode 版本上工作”"。
所有对 Borland 编译器的支持已被删除。代码很久以前就无法工作了。
Perl 永远不应该公开某些 Unicode 属性,这些属性被 Unicode 内部使用,并不打算公开。使用这些属性自 Perl 5.12 以来一直产生弃用警告消息。已删除的属性包括 Other_Alphabetic、Other_Default_Ignorable_Code_Point、Other_Grapheme_Extend、Other_ID_Continue、Other_ID_Start、Other_Lowercase、Other_Math 和 Other_Uppercase。
Perl 可以重新编译以包含任何或所有这些属性;说明在 "在 perluniprops 中的“Unicode 字符属性,Perl 不接受”" 中给出。
*{...}
运算符在传递对 IO 对象的引用时(如 *{*STDIN{IO}}
),会创建一个新的类型全局变量,其中只包含该 IO 对象。以前,它会字符串化为一个空字符串,但一些运算符会将其视为未定义,从而产生 "未初始化" 警告。现在它字符串化为 __ANONIO__ [perl #96326]。
此功能在 Perl 5.14 中已弃用,现已移除。CPAN 模块 Unicode::Casing 提供了更好的功能,而没有此功能所具有的缺点,如 5.14 文档中所述:https://perldoc.perl5.cn/5.14.0/perlunicode.html#User-Defined-Case-Mappings-%28for-serious-hackers-only%29
XSUB C 函数现在为 'static',也就是说,它们在编译单元之外不可见。用户可以使用新的 XS_EXTERNAL(name)
和 XS_INTERNAL(name)
宏来选择所需的链接行为。XSUB 的普通 XS(name)
声明将继续为兼容性声明非 'static' XSUB,但 XS 编译器,ExtUtils::ParseXS (xsubpp
) 默认情况下将发出 'static' XSUB。 ExtUtils::ParseXS 的行为可以通过 XS 使用 EXPORT_XSUB_SYMBOLS
关键字重新配置。有关详细信息,请参阅 perlxs。
不再允许削弱只读引用。它本来就不应该起作用,有时会导致崩溃。
尝试在将类型全局变量分配给标量后绑定标量,将改为绑定类型全局变量的 IO 槽中的句柄。这意味着不可能绑定标量本身。类似的问题影响了 tied
和 untie
:如果最后返回的是类型全局变量,则 tied $scalar
将在绑定标量上返回 false,而对这种绑定标量的 untie $scalar
将不会执行任何操作。
我们在 Perl 5.14.0 之前修复了这个问题,但它导致了一些 CPAN 模块出现问题,因此我们改为进行弃用周期。
现在弃用已移除,此错误已修复。因此,tie $scalar
将始终绑定标量,而不是它持有的句柄。要绑定句柄,请使用 tie *$scalar
(带有显式的星号)。同样适用于 tied *$scalar
和 untie *$scalar
。
xfork()
、xclose_on_exec()
和 xpipe_anon()
所有三个函数都是私有的、未公开的,并且未导出。它们似乎没有被 CPAN 上的任何代码使用。两个已被内联,一个已被完全删除。
$$
不再缓存 PID以前,如果从 C 中调用 fork(3),Perl 对 $$
的概念可能会与 getpid() 返回的值不同步。通过始终通过 getpid() 获取 $$
的值,消除了此潜在的错误。依赖缓存行为的代码将中断。如 核心增强 中所述,$$
现在是可写的,但它将在 fork 期间重置。
$$
和 getppid()
在 LinuxThreads 下不再模拟 POSIX 语义已删除在过时的 LinuxThreads 实现下 $$
和 getppid()
的 POSIX 模拟。这只会影响 Linux 2.4 用户和 Debian GNU/kFreeBSD 6.0 及更早版本的用户,而不会影响使用 NPTL 线程的大多数 Linux 安装。
这意味着 getppid()
与 $$
一样,现在始终保证返回操作系统对进程当前状态的理解,而不是 perl 的缓存版本。
有关详细信息,请参阅 $$ 的文档。
$<
、$>
、$(
和 $)
不再缓存与对 $$
和 getppid()
的更改类似,已删除 $<
、$>
、$(
和 $)
的内部缓存。
当我们缓存这些值时,如果有人(例如,嵌入 perl 的人)调用 sete?[ug]id()
而不更新 PL_e?[ug]id
,我们对它们是什么的理解将与现实脱节。考虑到 gete?[ug]id()
系统调用有多便宜,处理这种复杂性并不值得。
此更改将破坏少数使用 XS 级 PL_uid
、PL_gid
、PL_euid
或 PL_egid
变量的 CPAN 模块。
解决这些问题的方法是使用 PerlProc_gete?[ug]id()
来检索它们(例如,PerlProc_getuid()
),并且如果更改了 UID/GID/EUID/EGID,不要赋值给 PL_e?[ug]id
。由于 perl 将始终从操作系统检索这些值的最新版本,因此不再需要这样做。
quotemeta
和 \Q
引用哪些非 ASCII 字符已更改这不太可能导致实际问题,因为 Perl 不会对任何非 ASCII 字符赋予特殊含义,因此目前引用与否无关紧要。此更改修复了 bug [perl #77654],并将 Perl 的行为更符合 Unicode 的建议。参见 "quotemeta" in perlfunc.
改进了正则表达式中 Unicode 属性的性能
现在通过二分查找而不是线性查找来匹配代码点与 Unicode 属性。这意味着例如,对于 1000 个项目的属性,最坏情况是 10 次探测而不是 1000 次。这种低效率过去通过在哈希中永久存储给定探测的结果以及相邻 64 个代码点的结果来弥补,理论上认为附近的代码点很可能被搜索。每个正则表达式中每个 Unicode 属性的提及都使用单独的哈希。因此,qr/\p{foo}abc\p{foo}/
将生成两个哈希。一个实例中的任何探测都将对另一个实例未知,如果正则表达式用于许多不同的广泛分离的代码点,则哈希可以分别扩展到非常大。但是现在,只有一个哈希由给定属性的所有实例共享。这意味着如果 \p{foo}
在一个线程中的一个正则表达式中与 "A" 匹配,则结果将立即为所有正则表达式所知,并且使用内存的无情前进将大大减缓。
使用 use
关键字(例如,use 5.012
)的版本声明现在更快,因为它们在不加载 feature.pm 的情况下启用功能。
local $_
现在更快,因为它不再迭代它不会复制的魔法。
Perl 5.12.0 通过简单地不调用此类空方法来加快了定义空 DESTROY
方法(以防止自动加载)的类的对象的销毁速度。此版本通过不调用以 return
语句开头的任何 DESTROY
方法来进一步优化此优化。这对于仅用于调试的析构函数很有用
use constant DEBUG => 1;
sub DESTROY { return unless DEBUG; ... }
如果 DEBUG 设置为 0,则常量折叠将第一个语句减少为 return;
,从而触发此优化。
现在,为保存类型全局变量或写时复制标量的变量赋值的速度快得多。以前,类型全局变量将在被覆盖之前被字符串化,或者写时复制标量将在被覆盖之前被复制。
在空上下文中的 substr
赋值现在比以前快两倍多。substr
不是创建和返回一个特殊左值标量,然后将其赋值,而是修改原始字符串本身。
substr
在空上下文调用时不再计算返回值。
由于 File::Glob 的更改,Perl 的 glob
函数及其 <...>
等效项现在速度更快。模式拆分为单词的代码已用 C 重写,在某些情况下速度提高了 20%。
这不会影响 VMS 上的 glob
,因为它不使用 File::Glob。
短路运算符 &&
、||
和 //
在链式使用时(例如 $a || $b || $c
),由于减少了 optree 遍历,现在短路速度明显更快。
s///r
的实现减少了一次标量值的复制。
在左值标量上下文中对左值子例程的递归调用使用更少的内存。
Version::Requirements 现已弃用,请使用 CPAN::Meta::Requirements,它是一个直接替换。它将在 v5.17.0 中从 perl.git blead 中删除。
arybase -- 此新模块实现了 $[
变量。
PerlIO::mmap 0.010 已添加到 Perl 核心。
mmap
PerlIO 层不再由 perl 本身实现,而是被移到了新的 PerlIO::mmap 模块中。
这只是对选定模块更新的概述。有关更新的完整列表,请运行
$ corelist --diff 5.14.0 5.16.0
您也可以用您喜欢的版本替换 5.14.0。
Archive::Extract 已从版本 0.48 升级到 0.58。
包括一个针对 FreeBSD 的修复,仅当 unzip
位于 /usr/local/bin
中时才使用它,因为 FreeBSD 9.0 将在 /usr/bin
中提供一个有限的 unzip
。
Archive::Tar 已从版本 1.76 升级到 1.82。
调整以处理 >8gb (>0777777777777 八进制) 的文件,以及返回存档中文件 MD5SUM 的功能。
base 已从版本 2.16 升级到 2.18。
当加载的模块未定义 $VERSION
时,base
不再将模块的 $VERSION
设置为 "-1"。此更改已进行,因为 "-1" 在 UNIVERSAL::VERSION
内部使用的新的“宽松”标准下不是有效的版本号。(有关“宽松”版本标准的更多信息,请参阅 version。)
base
不再内部跳过加载它已经加载的模块,而是依赖 require
检查 %INC
。这修复了当 base
与清除 %INC
以强制重新加载模块的代码一起使用时的错误。
Carp 已从版本 1.20 升级到 1.26。
现在包含最后读取的文件句柄信息,并在文件和行号后添加一个点,就像来自die
的错误一样 [perl #106538]。
charnames 已从 1.18 版更新到 1.30 版。
charnames
现在可以使用一个新的选项 :loose
调用,它类似于现有的 :full
选项,但启用了 Unicode 松散名称匹配。详细信息请参见 "charnames 中的松散匹配"。
B::Deparse 已从 1.03 版升级到 1.14 版。这修复了许多反解析错误。
CGI 已从 3.52 版升级到 3.59 版。
它使用 CGI::Fast 中公开且有文档记录的 FCGI.pm API。CGI::Fast 使用的是一个 FCGI API,该 API 已被弃用,并且在十多年前从文档中删除。在 FCGI >= 0.70 或 FCGI <= 0.73 中使用此弃用的 API 会引入安全问题。 https://rt.cpan.org/Public/Bug/Display.html?id=68380 http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2011-2766
可能破坏代码的内容
url()
已修复为在使用 path=>1
或 path_info=>1
标志显式请求时返回 PATH_INFO
。
如果您的代码在 mod_rewrite(或兼容)下运行,并且您正在调用 self_url()
或您正在调用 url()
并传递 path_info=>1
,这些方法实际上将返回 PATH_INFO
,因为您已显式请求或 self_url()
已代表您请求。
自 2005 年 12 月 3.12 版本中引入此问题以来,此类 URL 中已省略 PATH_INFO
。
此错误非常古老,您的应用程序可能已经依赖于它或对其进行了变通处理。在升级到此版本之前,请检查应用程序。
受影响的方法调用的示例
$q->url(-absolute => 1, -query => 1, -path_info => 1);
$q->url(-path=>1);
$q->url(-full=>1,-path=>1);
$q->url(-rewrite=>1,-path=>1);
$q->self_url();
当未设置 Content-Length 时,我们不再从 STDIN 读取,防止没有 Content-Length 的请求有时会冻结。这与 CGI RFC 3875 一致,也与 CGI::Simple 一致。但是,某些命令行使用 CGI.pm 可能期望旧的行为。
此外,现在支持 DELETE HTTP 动词。
Compress::Zlib 已从版本 2.035 升级到 2.048。
IO::Compress::Zip 和 IO::Uncompress::Unzip 现在支持 LZMA(方法 14)。IO::Compress::Unzip 中的 CRC 问题已修复,现在支持流式存储上下文。并修复了 IO::Compress::Zip 中当内容大小正好为 0xFFFFFFFF 时出现的 Zip64 问题。
Digest::SHA 已从版本 5.61 升级到 5.71。
在 addfile 方法和 shasum 中添加了 BITS 模式。这使得通过文件/STDIN 进行部分字节输入成为可能,并允许 shasum 检查所有 8074 个 NIST 消息向量,而以前需要特殊的编程才能做到这一点。
Encode 已从版本 2.42 升级到 2.44。
添加了缺失的别名,修复了深度递归错误,并更新了各种文档。
解决了 Unicode.xs 中的“decode_xs n 字节堆溢出”安全漏洞(CVE-2011-2939)。(5.14.2)
ExtUtils::CBuilder 从版本 0.280203 更新到 0.280206。
新版本将其 CFLAGS 和 LDFLAGS 附加到其 Config.pm 对应项。
ExtUtils::ParseXS 已从版本 2.2210 升级到 3.16。
XS 编译器 xsubpp
背后的模块 ExtUtils::ParseXS 的大部分内容已被重写和清理。它已变得更加可扩展,并且现在最终使用了严格模式。
类型映射逻辑已移至一个单独的模块 ExtUtils::Typemaps 中。请参见上面的 "新模块和语义"。
有关完整变更集,请参阅 CPAN 上提供的 ExtUtils::ParseXS 变更日志。
File::Glob 已从版本 1.12 升级到 1.17。
在 Windows 上,波浪号(~)扩展现在会在检查 HOME
后检查 USERPROFILE
环境变量。
它有一个新的 :bsd_glob
导出标签,旨在替换 :glob
。与 :glob
一样,它会用一个不将 glob 模式拆分为单词的函数覆盖 glob
,但与 :glob
不同的是,它在标量上下文中会正确迭代,而不是返回最后一个文件。
还有一些其他更改影响了 Perl 自己的 glob
运算符(它在内部使用 File::Glob,除了在 VMS 上)。请参见 "性能增强" 和 "选定的错误修复"。
FindBin 从版本 1.50 更新到 1.51。
如果路径中存在与当前脚本同名的可执行脚本,它将不再返回错误结果。
HTTP::Tiny 已从版本 0.012 升级到 0.017。
添加了对使用 $ENV{http_proxy}
设置默认代理主机。
添加了所有常用 HTTP 动词的简写方法,一个用于 POST-ing x-www-form-urlencoded 数据的 post_form()
方法和一个 www_form_urlencode()
实用程序方法。
IO 已从版本 1.25_04 升级到 1.25_06,IO::Handle 已从版本 1.31 升级到 1.33。
这些升级共同修复了 IO::Handle 的 getline
和 getlines
方法的问题。当在特殊的 ARGV 句柄上调用这些方法时,会自动打开下一个文件,就像内置的 <>
和 readline
函数一样。但是,与内置函数不同,这些方法没有遵守调用者对 open 编译指示的使用,并将适当的 I/O 层应用于新打开的文件 [rt.cpan.org #66474]。
IPC::Cmd 已从版本 0.70 升级到 0.76。
现在可以使用 IPC::Open3 在 MSWin32 上捕获命令输出(STDOUT
和 STDERR
),而无需 IPC::Run。
IPC::Open3 已从版本 1.09 升级到 1.12。
修复了在 Windows 上 *STDIN
、*STDOUT
或 *STDERR
已本地化时阻止使用 open3
的错误。
修复了在 Windows 上阻止复制数字文件描述符的错误。
使用 "-" 作为程序名称的 open3
再次有效。这在版本 1.06(以及 Perl 5.14.0)中被破坏了 [perl #95748]。
Locale::Codes 已从版本 3.16 升级到 3.21。
添加了语言扩展代码 (langext) 和语言变体代码 (langvar),如 IANA 语言注册表中定义的那样。
添加了来自 ISO 639-5 的语言代码。
添加了来自 IANA 语言子标签注册表的语言/脚本代码。
修复了未初始化值警告 [rt.cpan.org #67438]。
修复了 all_XXX_codes 和 all_XXX_names 函数的返回值 [rt.cpan.org #69100]。
重新组织模块以将 Locale::MODULE 移动到 Locale::Codes::MODULE,以便更轻松地进行未来的添加。最初的四个模块(Locale::Language、Locale::Currency、Locale::Country、Locale::Script)将继续工作,但所有新的代码集都将在 Locale::Codes 命名空间中添加。
code2XXX、XXX2code、all_XXX_codes 和 all_XXX_names 函数现在支持已停用的代码。所有代码集现在都可以通过常量或名称指定。以前,它们只能通过常量指定。
alias_code 函数是为了向后兼容而存在的。它已被 rename_country_code 替换。alias_code 函数将在 2013 年 9 月之后一段时间内被移除。
所有工作现在都在中央模块 (Locale::Codes) 中完成。以前,一些工作仍在包装模块 (Locale::Codes::*) 中完成。添加了 ISO 639-5 中定义的语言族代码 (langfam)。
Math::BigFloat 已从 1.993 版升级到 1.997 版。
numify
方法已更正为返回规范化的 Perl 数字(0 + $thing
的结果),而不是字符串 [rt.cpan.org #66732]。
Math::BigInt 已从 1.994 版升级到 1.998 版。
它提供了一个新的 bsgn
方法,作为 babs
方法的补充。
它修复了内部 objectify
函数对“外部对象”的处理,以便将它们转换为适当的类 (Math::BigInt 或 Math::BigFloat)。
Math::BigRat 已从 0.2602 版升级到 0.2603 版。
包含 -1/2 的 Math::BigRat 对象上的 int()
现在会创建一个包含 0 的 Math::BigInt,而不是 -0。 Math::BigInt 甚至不支持负零,因此结果对象实际上是格式错误的 [perl #95530]。
Math::Complex 已从 1.56 版升级到 1.59 版,Math::Trig 已从 1.2 版升级到 1.22 版。
修复包括:更正复制构造函数的使用;修复使用数字格式说明符的极坐标格式;以及更稳定的 great_circle_direction
算法。
Module::CoreList 已从 2.51 版升级到 2.66 版。
corelist
实用程序现在理解 -r
选项以显示 Perl 发布日期,以及 --diff
选项以打印两个 Perl 发行版之间的 modlib 更改集。
Module::Metadata 已从 1.000004 版升级到 1.000009 版。
添加了 provides
方法以正确生成 CPAN META provides 数据结构;不建议使用 package_versions_from_directory
。
ODBM_File 已从 1.10 版升级到 1.12 版。
XS 代码现在使用 `PERL_NO_GET_CONTEXT` 编译,这将有助于在 ithreads 下提高性能。
open 已从版本 1.08 升级到 1.10。
它不再在没有 ":std" 指令的情况下关闭标准句柄上的层。类似地,当使用 ":std" 指令调用时,它现在会在应用新层之前清除 STDERR 上的层,而不仅仅是 STDIN 和 STDOUT [perl #92728]。
overload 已从版本 1.13 升级到 1.18。
overload::Overloaded
不再调用类上的 `can`,而是使用其他方法来确定对象是否具有重载。它从未正确调用 `can`,因为重载不尊重 AUTOLOAD。因此,自动加载方法并实现 `can` 的类不再需要考虑重载 [perl #40333]。
现在会针对无效参数生成警告。请参阅 "新诊断"。
PerlIO::scalar 已从版本 0.11 升级到 0.14。
(这是实现 `open $fh, '>', \$scalar` 的模块。)
它修复了 `open my $fh, ">", \$scalar` 在 `$scalar` 是一个写时复制标量时无法工作的问题。(5.14.2)
它还修复了在 `$scalar` 被分配了一个类型全局变量时,使用 `readline` 或 `<$fh>` 发生的挂起问题 [perl #92258]。
它不再在 `seek` 期间假设 `$scalar` 在内部是一个字符串。如果它没有崩溃,它就快崩溃了 [perl #92706]。此外,内部打印例程不再假设 `seek` 设置的位置有效,而是将字符串扩展到该位置,用空字节填充中间字节(在旧长度和搜索位置之间) [perl #78980]。
如果 `$scalar` 包含一个引用,则现在可以将数据打印到内存中句柄,在修改之前将引用转换为字符串。引用以前被视为空字符串。
如果 `$scalar` 恰好包含一个数字,但没有字符串缓冲区,则将数据打印到内存中句柄不再会崩溃。
将数据打印到内存中句柄不再会创建会混淆正则表达式引擎的标量 [perl #108398]。
Pod::Functions 已从版本 1.04 升级到 1.05。
Functions.pm 现在在 perl 构建时从 perlfunc.pod 中的注释生成。这将确保 Pod::Functions 和 perlfunc 保持同步。
Pod::Html 已从版本 1.11 升级到 1.1502。
这是 Pod::Html 的一个全面重写,它在内部使用 Pod::Simple。输出已发生重大变化。
Pod::Perldoc 已从版本 3.15_03 升级到 3.17。
它修正了 VMS 上的搜索路径 [perl #90640]。(5.14.1)
-v 选项现在可以获取 $0
的正确部分。
此升级包含许多重大修复。有关更多信息,请参阅 CPAN 上的更改日志。
POSIX 已从版本 1.24 升级到 1.30。
POSIX 不再使用 AutoLoader。任何依赖此实现细节的代码都是有错误的,并且可能会因为此更改而失败。模块的 Perl 代码已大大简化,行数减少了一半左右,功能没有变化。XS 代码已重构,以将共享对象的尺寸减少约 12%,功能没有变化。现在有更多 POSIX 函数的测试。
sigsuspend
和 pause
现在在返回之前运行信号处理程序,因为这两个函数的重点是等待信号到达,然后在信号触发后返回。延迟或“安全”信号阻止了这种情况发生,可能会导致竞争条件 [perl #107216]。
POSIX::sleep
现在直接调用底层操作系统 sleep
函数,而不是作为 CORE::sleep
的 Perl 包装器。POSIX::dup2
现在在 Win32 上返回正确的值(即文件描述符)。POSIX::SigSet
sigsuspend
和 sigpending
以及 POSIX::pause
现在在返回其调用者之前立即调度安全信号。
POSIX::Termios::setattr
现在将第三个参数默认为 TCSANOW
,而不是 0。在大多数平台上,TCSANOW
被定义为 0,但在某些平台上,0 不是有效参数,这会导致带有默认值的调用失败。
Socket 已从版本 1.94 升级到 2.001。
它具有用于处理 IPv6 套接字的新函数和常量。
pack_ipv6_mreq
unpack_ipv6_mreq
IPV6_ADD_MEMBERSHIP
IPV6_DROP_MEMBERSHIP
IPV6_MTU
IPV6_MTU_DISCOVER
IPV6_MULTICAST_HOPS
IPV6_MULTICAST_IF
IPV6_MULTICAST_LOOP
IPV6_UNICAST_HOPS
IPV6_V6ONLY
Storable 已从版本 2.27 升级到 2.34。
它不再在冻结和解冻时将写时复制标量转换为只读标量。
Sys::Syslog 已从版本 0.27 升级到 0.29。
此升级修复了许多未解决的错误。
Term::ANSIColor 已从版本 3.00 升级到 3.01。
仅将初始数组引用解释为颜色列表,而不是任何初始引用,允许 colored 函数在定义了字符串化的对象上正常工作。
Term::ReadLine 已从版本 1.07 升级到 1.09。
Term::ReadLine 现在支持任何事件循环,包括未发布的事件循环和简单的 IO::Select 循环,无需为任何特定框架重写现有代码 [perl #108470]。
threads::shared 已从版本 1.37 升级到 1.40。
如果共享对象仅被共享数据结构引用,则共享对象上的析构函数有时会被忽略。这已基本修复,但如果对象在全局销毁时仍然存在,则析构函数可能仍然会被忽略 [perl #98204]。
Unicode::Collate 已从版本 0.73 升级到 0.89。
更新到 CLDR 1.9.1
语言环境更新到 CLDR 2.0:mk、mt、nb、nn、ro、ru、sk、sr、sv、uk、zh__pinyin、zh__stroke
新增支持的语言环境:bn、fa、ml、mr、or、pa、sa、si、si__dictionary、sr_Latn、sv__reformed、ta、te、th、ur、wae。
为以下语言环境定制了兼容性表意文字以及统一表意文字:ja、ko、zh__big5han、zh__gb2312han、zh__pinyin、zh__stroke。
现在在 @INC 中搜索 Locale/*.pl 文件。
Unicode::Normalize 已从版本 1.10 升级到 1.14。
修复了从核心移除 unicore/CompositionExclusions.txt 的问题。
Unicode::UCD 已从版本 0.32 升级到 0.43。
这添加了四个新函数:prop_aliases()
和 prop_value_aliases()
,用于查找所有 Unicode 批准的属性名称同义词,或将一个名称转换为另一个名称;prop_invlist
返回与给定 Unicode 二进制属性匹配的所有代码点;prop_invmap
返回给定 Unicode 属性的完整规范。
Win32API::File 已从版本 0.1101 升级到 0.1200。
添加了 SetStdHandle 和 GetStdHandle 函数
正如 Perl 5.14.0 的发行说明中所承诺的那样,以下模块已从核心发行版中移除,如果需要,应从 CPAN 安装。
Devel::DProf 已从 Perl 核心移除。先前版本为 20110228.00。
Shell 已从 Perl 核心移除。先前版本为 0.72_01。
几个旧的 perl4 风格的库,这些库在 5.14 中已弃用,现在已移除
abbrev.pl assert.pl bigfloat.pl bigint.pl bigrat.pl cacheout.pl
complete.pl ctime.pl dotsh.pl exceptions.pl fastcwd.pl flush.pl
getcwd.pl getopt.pl getopts.pl hostname.pl importenv.pl
lib/find{,depth}.pl look.pl newgetopt.pl open2.pl open3.pl
pwd.pl shellwords.pl stat.pl tainted.pl termcap.pl timelocal.pl
它们可以在 CPAN 上找到,名为 Perl4::CoreLibs。
perldtrace 描述了 Perl 的 DTrace 支持,列出了提供的探针并提供了使用示例。
本文档旨在提供 Perl 中实验性功能的列表。它仍在开发中。
这是一个新的 OO 教程。它侧重于基本的 OO 概念,然后建议读者从 CPAN 中选择一个 OO 框架。
新手册以空前的详细程度描述了 XS 类型映射机制,并将新文档与从 perlxs 中提取的信息以及以前非官方的所有核心类型映射列表相结合。
HV API 长期以来接受负长度来表示键是 UTF8。现在已记录在案。
boolSV()
宏现在已记录在案。
dbmopen
将 0 模式视为特殊情况,这将阻止创建不存在的文件。这种情况自 Perl 5.000 以来一直存在,但从未在任何地方记录过。现在 perlfunc 条目提到了它 [perl #90064]。
由于历史原因,open $fh, '<:', ...
应用平台的默认层(Unix 上为 :raw
,Windows 上为 :crlf
),忽略 open.pm 中声明的任何内容。这似乎是一个非常有用的功能,它已在 perlfunc 和 open 中记录。
split
的条目已重写。现在比以前清晰得多。
添加了一个新部分,使用 XSUB 自动加载,它解释了访问自动加载子例程名称的两个 API。
一些 perlguts 中的函数描述令人困惑,因为不清楚它们指的是描述上方还是下方的函数。现在已澄清 [perl #91790]。
本文档已从头开始重写,并扩展了其对各种 OO 概念的覆盖范围。
智能匹配运算符的文档已重新整理,并从 perlsyn 移动到它所属的 perlop。
它也针对左侧为 undef
的情况进行了更正。不同智能匹配行为的列表中有一个项目位置错误。
省略号语句 (...
) 的文档已重新整理,并从 perlop 移动到 perlsyn。
位运算符的解释已扩展,以解释它们如何在 Unicode 字符串 (5.14.1) 上工作。
为 m//g
添加了更多示例 (5.14.1)。
已记录 <<\FOO
here-doc 语法 (5.14.1)。
现在有一个标准约定用于命名%^H
中的键,在键命名中进行了说明。
用于检查污染的示例函数包含一个细微的错误。$@
需要被局部化以防止它改变函数外部此全局变量的值。检查此问题的首选方法仍然是"Scalar::Util 中的 tainted"。
perllol已扩展,包含使用 Perl 5.14.0 (5.14.1) 中引入的新的push $scalar
语法的示例。
perlmod现在明确说明某些类型的显式符号表操作不受支持。这将有效地将已经存在的情况进行了编码 [perl #78074]。
关于使用哪些格式化代码的提示已得到纠正并大大扩展。
现在有几个用于预览已编辑的 POD 文件的示例单行命令。
(*COMMIT)
指令现在列在正确的部分 (没有参数的动词) 中。
perlrun 已经过重大清理。最值得注意的是,-0 标志的 -0x... 形式已经得到澄清,并且关于环境变量的最后一部分已经得到纠正和扩展 (5.14.1)。
($;) 原型语法已经存在相当长的时间,现在在 perlsub 中有说明。它允许一元函数具有与列表运算符相同的优先级。
已经记录了绑定句柄所需的语法。
$! 的文档已经得到纠正和澄清。它过去曾指出 $! 可以是 undef
,但事实并非如此。也不清楚系统调用是设置 C 的 errno
还是 Perl 的 $!
[perl #91614]。
$$ 的文档已经修改,增加了有关更改进程 ID 的额外注意事项。
perlxs 已扩展,包含有关内联类型映射的文档。
perlapi 的部分内容已经得到澄清,并且一些 C 函数的 Perl 等效项已作为一种额外的解释方式添加。
对 perlre 和 perlrecharclass 中的某些部分进行了澄清。
旧的 OO 教程,perltoot、perltooc 和 perlboot,已被删除。perlbot(对象技巧包)文档也被删除。
开发版本的 perldelta 文件不再与 perl 打包在一起。这些文件仍然可以在 perl 源代码库中找到。
对诊断输出(包括警告和致命错误消息)进行了以下添加或更改。有关诊断消息的完整列表,请参阅 perldiag。
当 caller
尝试设置 @DB::args
但发现它被绑定时,会发生此错误。在添加此错误之前,它以前会崩溃。
此错误是 tie
运算符在绑定特殊数组(如 @_
)之前进行的安全检查的一部分。您不应该看到此消息。
当使用 &foo
语法或通过引用调用 CORE::
命名空间中的子例程时,会发生这种情况。此包中的一些子例程尚无法以这种方式调用,但必须作为裸词调用。请参阅上面的 "CORE
命名空间中的子例程"。
当您尝试在传递给 eval
的字符串中激活源代码过滤器(通常是通过加载源代码过滤器模块)时,会发生此新错误,前提是在 unicode_eval
特性下。
现在,长期弃用的 defined(@array)
也会针对包变量发出警告。以前它只针对词法变量发出警告。
当在数组或哈希上使用 length
而不是 scalar(@array)
或 scalar(keys %hash)
时,会产生此新警告。
attributes.pm 现在在将 :lvalue 属性应用于已定义的 Perl 子例程时发出此警告,因为这样做可能会产生意想不到的副作用。
此警告属于“overload”类别,当 overload 编译指示遇到无法识别的参数时产生,可能是输入的运算符错误。
此新警告用于捕获在版本检查中错误使用 $[
的情况。$]
而不是 $[
包含版本号。
现在,对从 lvalue 子例程返回的临时标量进行赋值会产生此警告 [perl #31946]。
\E
除非在 \Q
、\L
或 \U
之前,否则不会执行任何操作。
"sort 现在是保留字"
当 sort
在没有参数的情况下调用,后面跟着 ;
或 )
时,以前会发生此错误。(例如,sort;
会导致死亡,但 {sort}
则可以。)此错误消息是在 Perl 3 中添加的,用于捕获类似 close(sort)
的代码,这些代码将不再起作用。二十多年后,此消息不再合适。现在,没有参数的 sort
始终允许,并返回一个空列表,就像它在已经允许的情况下那样 [perl #90030]。
当数组或哈希位于 =~
运算符的左侧时产生的“正在应用模式匹配...”或类似警告现在会提到变量的名称。
"尝试释放不存在的共享字符串" 的拼写已从 "non-existent" 更正为 "nonexistent"。它已经在 perldiag 中以正确的拼写列出。
在主题化器之外使用 default
和 when
的错误消息已标准化为与 continue
和循环控制的错误消息相匹配。它们现在显示为“在主题化器之外无法使用 'default'”和“在主题化器之外无法使用 'when'”。它们以前都是“在主题化器之外无法使用 when()” [perl #91514]。
消息“代码点 0x%X 不是 Unicode,没有属性与之匹配;所有反向属性都匹配”已更改为“代码点 0x%X 不是 Unicode,所有 \p{} 匹配失败;所有 \P{} 匹配成功”。
常量子例程的重新定义警告以前是强制性的,即使在 no warnings
下也会发生。现在它们会尊重 warnings 编译指示。
现在可以通过 no warnings
[perl #111656] 来抑制 "glob failed" 警告消息。
对于负数,Invalid version format 错误消息现在在括号中显示 "negative version number",而不是 "non-numeric data"。
两个警告 Possible attempt to put comments in qw() list 和 Possible attempt to separate words with commas 不再是互斥的:同一个 qw
结构可能会产生两者。
当 $_
是隐式且未定义时,y///r
的未初始化警告现在会像操作符的非-/r 变体一样,提及变量名。
'Use of "foo" without parentheses is ambiguous' 警告已扩展到也适用于具有 (;$) 原型的用户定义子例程,而不仅仅是内置函数。
提及包含 Unicode 字符的词法 (my
) 变量名称的警告现在会尊重输出句柄上 :utf8
层的存在与否,而不是无论如何都输出 UTF8。此外,传递给 $SIG{__WARN__}
处理程序的字符串中包含了正确的名称,而不是原始的 UTF8 字节。
h2ph 过去生成以下形式的代码
unless(defined(&FOO)) {
sub FOO () {42;}
}
但子例程是编译时声明,因此不受条件影响。现在已更正为在子例程周围发出字符串 eval
[perl #99368]。
splain 不再发出带有重复第一行号的回溯。
这个
Uncaught exception from user code:
Cannot fwiddle the fwuddle at -e line 1.
at -e line 1
main::baz() called at -e line 1
main::bar() called at -e line 1
main::foo() called at -e line 1
已变为这个
Uncaught exception from user code:
Cannot fwiddle the fwuddle at -e line 1.
main::baz() called at -e line 1
main::bar() called at -e line 1
main::foo() called at -e line 1
一些错误消息包含多行,这些行在 perldiag 中被列为单独的条目。splain 已学会在这些情况下找到单独的条目,而不是简单地无法找到消息。
这是一个新实用程序,作为 IO::Compress::Base 升级的一部分包含在内。
zipdetails 显示有关 zip 文件内部记录结构的信息。它不关心显示存储在 zip 文件中的压缩数据的任何详细信息。
regexp.h 已修改以兼容 GCC 的 -Werror 选项,如一些包含 perl 头文件(5.14.1)的项目所使用。
USE_LOCALE{,_COLLATE,_CTYPE,_NUMERIC}
已添加到 perl -V 的输出中,因为它们会影响解释器二进制文件的行为(尽管只在很小的范围内)。
IPC::Open2 的代码和测试已从 ext/IPC-Open2 移动到 ext/IPC-Open3,因为 IPC::Open2::open2()
是作为 IPC::Open3::_open3()
的一个薄包装器实现的,因此与它紧密耦合。
魔术类型和魔术 vtable 现在从新脚本 regen/mg_vtable.pl 中的数据生成,而不是手动维护。由于不同的 EBCDIC 变体无法就 '~' 的代码点达成一致,因此字符到代码点的转换在构建时由 generate_uudmap 完成到一个新的生成头文件 mg_data.h 中。PL_vtbl_bm
和 PL_vtbl_fm
现在由预处理器定义为 PL_vtbl_regexp
,而不是作为不同的 C 变量。PL_vtbl_sig
已被删除。
使用 -DPERL_GLOBAL_STRUCT
构建再次有效。此配置通常不使用。
使用 MAD 配置的 Perl 现在在 OP 被释放时正确地释放 MADPROP
结构。MADPROP
现在使用 PerlMemShared_malloc()
分配。
makedef.pl 已重构。这应该不会对任何使用它作为其构建一部分的平台(AIX、VMS、Win32)产生明显的影响。
useperlio
现在无法禁用。
文件 global.sym 不再需要,已被删除。它包含所有导出函数的列表,这是由 regen/embed.pl 从 embed.fnc 和 regen/opcodes 中的数据生成的几个文件之一。代码已重构,因此 global.sym 的唯一用户 makedef.pl 现在直接读取 embed.fnc 和 regen/opcodes,从而无需将导出函数列表存储在中间文件中。
由于 global.sym 从未安装,因此此更改在构建过程之外应该是不可见的。
pod/buildtoc(构建过程用于构建 perltoc)已重构并简化。它现在只包含构建 perltoc 的代码;重新生成 Makefile 的代码已移至 Porting/pod_rules.pl。如果此更改对构建过程有任何实质性影响,则是一个错误。
pod/roffitall 现在由 pod/buildtoc 构建,而不是与发行版一起提供。它的手册页列表现在已生成(因此是最新的)。另请参见 RT #103202,了解一个未解决的相关问题。
XS::Typemap
的手册页不再安装。XS::Typemap
是一个测试模块,不会安装,因此安装其文档毫无意义。
-Dusesitecustomize 和 -Duserelocatableinc 选项现在可以正常协同工作。
从 1.7 版开始,Cygwin 支持原生 UTF-8 路径。如果 Perl 在该环境下构建,目录和文件名将使用 UTF-8 编码。
Cygwin 不会初始化所有原始 Win32 环境变量。有关新添加的 Cygwin::sync_winenv()
函数 [perl #110190] 以及更多链接的讨论,请参见 README.cygwin。
HP-UX PA-RISC/64 现在支持 gcc-4.x
一个修复 socketsize 的补丁现在使测试套件在 HP-UX PA-RISC 上通过 64bitall 构建。(5.14.2)
删除不必要的包含,修复各种编译器警告,并关闭 vms/vms.c 中的一些未关闭的注释。
从 VMS 构建中删除 sockadapt 层。
对 v7.0 之前的 VMS 版本和 v6.0 之前的 DEC C 版本的显式支持已被删除。
从 Perl 5.10.1 开始,自制的 stat
包装器无法区分包含下划线的目录名称和在相同位置包含点的相同文件名称(例如,t/test_pl 作为目录和 t/test.pl 作为文件)。此问题已得到纠正。
VMS 上的构建现在允许 Perl 中 C 代码中生成的符号名称超过 31 个字符。现在可以自由创建诸如 Perl__it_was_the_best_of_times_it_was_the_worst_of_times
之类的符号,而不会导致 VMS 链接器停止工作。
GNU/Hurd 上的许多构建和测试失败已通过构建 DBM 模块的提示、库搜索路径的检测以及大文件支持的启用得到解决。
Perl 现在在 OpenVOS 上使用动态链接构建,OpenVOS 的最低支持版本现在是 Release 17.1.0。
CC workshop C++ 编译器现在在没有 cc 的系统上被检测到并使用。
格式的编译表示现在通过其 PERL_MAGIC_fm
的 mg_ptr
存储。以前它存储在字符串缓冲区中,超出 SvLEN()
,字符串的常规结尾。SvCOMPILED()
和 SvCOMPILED_{on,off}()
现在仅出于 XS 代码的兼容性而存在。第一个始终为 0,另外两个现在是无操作。(5.14.1)
一些全局变量被标记为const
,解释器结构中的成员被重新排序,操作码也被重新排序。OP_AELEMFAST
操作被拆分为 OP_AELEMFAST
和 OP_AELEMFAST_LEX
。
当清空哈希中的元素(例如,通过 undef(%h) 或 %h=())时,HvARRAY 字段不再被临时置零。在释放的元素上调用的任何析构函数都会看到剩余的元素。因此,%h=() 变得更像 delete $h{$_} for keys %h
。
Boyer-Moore 编译的标量现在是 PVMG,Boyer-Moore 表现在通过其 PERL_MAGIC_bm
的 mg_ptr 存储。以前它们是 PVGV,表存储在字符串缓冲区中,超过 SvLEN()
。这消除了核心在 SvLEN()
之外存储数据的最后一个地方。
Perl_sv_magic()
中的简化逻辑对涉及未知魔术类型的错误情况引入了细微的行为变化。以前,如果 Perl_sv_magic()
传递了一个它不认识的魔术类型,它会
如果只读,则 croak "试图修改只读值"
如果 SV 碰巧已经具有此魔术,则不返回错误
否则 croak "不知道如何处理类型为 \\%o 的魔术"
现在它将始终 croak "不知道如何处理类型为 \\%o 的魔术",即使在只读值或已经具有未知魔术类型的 SV 上也是如此。
实验性的 fetch_cop_label
函数已重命名为 cop_fetch_label
。
cop_store_label
函数已添加到 API 中,但处于实验阶段。
embedvar.h 已简化,并且针对默认(非多重性)配置,已删除 PL_* 变量的一级宏间接寻址。PERLVAR*() 宏现在直接将其参数扩展为诸如 PL_defgv
之类的标记,而不是扩展为 PL_Idefgv
,其中 embedvar.h 定义了一个宏将 PL_Idefgv
映射到 PL_defgv
。与实现有无端亲密关系的 XS 代码可能需要更新。
已添加一个 API 来明确选择是否导出 XSUB 符号。有关更多详细信息,请参阅提交 e64345f8 的注释。
is_gv_magical_sv
函数已被移除并合并到 gv_fetchpvn_flags
中。它以前用于确定在右值上下文中是否应该自动创建 GV。现在它已被新的 GV_ADDMG
标志(不是 API 的一部分)取代。
当输入为格式错误的 UTF-8、允许格式错误且关闭了 utf8
警告时,utf8n_to_uvuni()
函数返回的代码点现在是 Unicode 替换字符,只要格式错误使得无法计算出明确定义的代码点。以前返回的值基本上是垃圾。唯一具有明确定义值的格式错误是零长度字符串(返回 0)和过长的 UTF-8 序列。
填充列表现在被标记为 AvREAL
;即,引用计数。它们一直都是引用计数的,但没有被标记为真实,因为 pad.c 自己进行清理,而不是使用 sv.c 中的常规清理代码。这在线程克隆中造成了问题,因此现在 AvREAL
标志被打开,但在 pad.c 中释放填充列表之前(在 pad.c 完成对填充的自定义释放之后)被关闭。
构成 Perl 核心所有 C 文件都已转换为 UTF-8。
这些新函数作为 Unicode 符号工作的一部分被添加。
HvNAMELEN
HvNAMEUTF8
HvENAMELEN
HvENAMEUTF8
gv_init_pv
gv_init_pvn
gv_init_pvsv
gv_fetchmeth_pv
gv_fetchmeth_pvn
gv_fetchmeth_sv
gv_fetchmeth_pv_autoload
gv_fetchmeth_pvn_autoload
gv_fetchmeth_sv_autoload
gv_fetchmethod_pv_flags
gv_fetchmethod_pvn_flags
gv_fetchmethod_sv_flags
gv_autoload_pv
gv_autoload_pvn
gv_autoload_sv
newGVgen_flags
sv_derived_from_pv
sv_derived_from_pvn
sv_derived_from_sv
sv_does_pv
sv_does_pvn
sv_does_sv
whichsig_pv
whichsig_pvn
whichsig_sv
newCONSTSUB_flags
gv_fetchmethod_*_flags
函数(如 gv_fetchmethod_flags
)是实验性的,可能会在将来的版本中发生变化。
以下函数已添加。这些不是 API 的一部分。
GvNAMEUTF8
GvENAMELEN
GvENAME_HEK
CopSTASH_flags
CopSTASH_flags_set
PmopSTASH_flags
PmopSTASH_flags_set
sv_sethek
HEKfARG
还有一个与 SVf
相对应的 HEKf
宏,用于在格式化字符串中插值 HEK。
sv_catpvn_flags
接受两个新的内部专用标志,SV_CATBYTES
和 SV_CATUTF8
,它们告诉它要连接的字符数组是否是 UTF8。这允许比创建临时 SV 传递给 sv_catsv
更有效的连接。
对于 XS AUTOLOAD 子例程,$AUTOLOAD 再次被设置,就像在 5.6.0 中一样。这除了设置 SvPVX(cv)
,是为了与 5.8 到 5.14 兼容。参见 "perlguts 中的用 XSUB 自动加载"。
Perl 现在检查由 MRO 插件返回的数组(线性化的 isa)是否以创建该数组的类的名称开头,而不是假设它确实如此。这可以防止在方法查找期间跳过第一个元素。这也意味着 mro::get_linear_isa
可能返回一个比 MRO 插件提供的数组多一个元素的数组 [perl #94306]。
PL_curstash
现在是引用计数的。
现在 PL_hints
($^H
) 中有特性包提示,版本声明使用它来避免加载 feature.pm。提示位的一种设置表示“自定义”特性包,这意味着 %^H
中的条目仍然适用。feature.pm 使用它。
HINT_FEATURE_MASK
宏在 perl.h 中定义,以及其他提示。用于设置和测试特性和包的其他宏在新的 feature.h 中。FEATURE_IS_ENABLED
(已移至 feature.h)不再在整个代码库中使用,而是使用更具体的宏,例如 FEATURE_SAY_IS_ENABLED
,这些宏在 feature.h 中定义。
lib/feature.pm 现在是一个生成的文件,由新的 regen/feature.pl 脚本创建,该脚本还生成 feature.h。
绑定数组现在始终是 AvREAL
。如果 @_
或 DB::args
是绑定的,它将首先被具象化,以确保始终如此。
添加了两个新函数 utf8_to_uvchr_buf()
和 utf8_to_uvuni_buf()
。它们与 utf8_to_uvchr
和 utf8_to_uvuni
(现在已弃用)相同,但它们接受一个额外的参数,用于防止读取超出输入字符串的末尾。请参阅 "perlapi 中的 utf8_to_uvchr_buf" 和 "perlapi 中的 utf8_to_uvuni_buf"。
正则表达式引擎现在在 Unicode 下进行 TRIE 不区分大小写的匹配。这可能会改变 use re 'debug';
的输出,并且会加速各种操作。
有一个新的 wrap_op_checker()
函数,它提供了一种线程安全的替代方法,用于直接写入 PL_check
。
已修复一个错误,该错误会导致在迭代下一个要迭代的两个哈希元素时出现“在迭代中使用已释放的值”错误 [perl #85026]。(5.14.1)
在 void 上下文中删除当前哈希迭代器(哈希元素,将在下次调用 each
时返回)以前不会释放它 [perl #85026]。
通过 delete $Class::{method}
语法删除方法以前会在 void 上下文中调用时更新方法缓存,但在标量或列表上下文中不会更新。
当在 void 上下文中删除哈希元素时,现在会在释放值之前释放内部哈希条目,以防止由后者释放调用的析构函数看到不一致状态的哈希。如果析构函数释放了哈希本身,则可能会导致双重释放 [perl #100340]。
Perl 5.12.0 中的 keys
优化是为了在空哈希上更快,导致在删除最后一个元素后调用 each
不会重置迭代器。
释放深度嵌套的哈希不再会导致崩溃 [perl #44225]。
现在可以使用 XS 代码创建包含没有值的元素的哈希。哈希元素和切片运算符在左值上下文中处理这些元素时曾经会崩溃。现在它们会产生“尝试修改不可创建的哈希值”错误消息。
如果对哈希或数组的列表赋值触发了析构函数,这些析构函数释放了哈希或数组本身,就会导致崩溃。这种情况不再发生 [perl #107440]。
以前可以释放本地化数组或哈希的 typeglob(例如,local @{"x"}; delete $::{x}
),导致在作用域退出时崩溃。
一些影响 Hash::Util 的核心错误已修复:锁定作为 glob 复制的哈希元素不再导致对它的下一个赋值破坏 glob(5.14.2),并且解锁包含写时复制标量的哈希元素不再导致对该标量的修改修改共享相同字符串缓冲区的其他标量。
newHVhv
XS 函数现在可以在绑定哈希上工作,而不是崩溃或返回空哈希。
SvIsCOW
C 宏现在对 typeglob 的只读副本返回 false,例如由
$hash{elem} = *foo;
Hash::Util::lock_value %hash, 'elem';
它以前返回 true。
SvPVutf8
C 函数不再尝试修改其参数,从而导致错误 [perl #108994]。
SvPVutf8
现在可以与魔法变量一起正常工作。
SvPVbyte
现在可以与非 PV 正常工作。
当遇到格式错误的 UTF-8 输入时,可由 XS 调用的函数 is_utf8_string()
、is_utf8_string_loc()
和 is_utf8_string_loclen()
可能会读取超出输入字符串末尾最多 12 个字节。这种情况不再发生。[perl #32080]。但是,目前,is_utf8_char()
仍然存在此缺陷,请参阅上面的 "is_utf8_char()"。
C 级别的 pregcomp
函数可能会对模式是否为 UTF8 感到困惑,如果模式是重载的、绑定的或其他魔法标量 [perl #101940]。
绑定 %^H
不再导致 perl 在进入编译作用域时崩溃或忽略 %^H
的内容 [perl #106282]。
eval $string
和 require
在编译时不会本地化 %^H
,如果在编译 eval
调用本身时它为空。这会导致可怕的副作用,例如 use re "/m"
启用其他标志,而周围代码试图为其调用者启用这些标志 [perl #68750]。
eval $string
和 require
现在不再在运行时本地化提示($^H
和 %^H
),而只在编译 $string 或所需文件时本地化。这使得 BEGIN { $^H{foo}=7 }
等同于 BEGIN { eval '$^H{foo}=7' }
[perl #70151]。
从 XS 代码(通过 newXS
或 newATTRSUB
)创建 BEGIN 块,在完成时,会使当前编译代码的提示成为当前提示。这会导致在非警告范围内出现警告。
写时复制或共享哈希键标量在 5.8.0 中引入,但大多数 Perl 代码没有遇到它们(它们主要用于内部)。Perl 5.10.0 扩展了它们,使得将 __PACKAGE__
或哈希键分配给标量会使其成为写时复制。Perl 的几个部分没有更新以考虑它们,但现在已修复。
utf8::decode
存在一个严重的错误,会修改写时复制标量的字符串缓冲区(即跳过复制)。这会导致哈希具有两个具有相同键的元素 [perl #91834]。(5.14.2)
左值子例程不允许返回 COW 标量。这在 Perl 5.12.3 和 5.14.0 中针对左值标量上下文进行了修复,但列表上下文直到此版本才修复。
包含写时复制值的受限哈希(参见 fields 准则)的元素无法删除,也不能清除此类哈希(%hash = ()
)。(5.14.2)
本地化一个绑定变量,如果它包含一个写时复制字符串,则会使其成为只读。(5.14.2)
将写时复制字符串分配给存储元素不再导致双重释放。无论此更改如何,此类分配的结果仍然是未定义的。
将写时复制字符串分配给绑定变量不再阻止该变量被绑定,如果它恰好是内部的 PVMG 或 PVLV。
对返回写时复制标量的绑定变量进行替换,以前会导致断言失败或“尝试释放不存在的共享字符串”警告。
这是一个来自 5.12 的回归:在 5.14.0 中,按位赋值运算符 |=
、^=
和 &=
开始在左侧为写时复制字符串时使其变为未定义 [perl #108480]。
Storable、Devel::Peek 和 PerlIO::scalar 存在类似的问题。请参见上面的 "更新的模块和准则"。
dumpvar.pl 以及调试器中的 x
命令已修复,以处理祝福到名称包含“=”的类的对象。此类对象的内容以前不会被转储 [perl #101814]。
用于重新启动调试器会话的“R”命令已修复,使其在 Windows 或任何其他缺少 POSIX::_SC_OPEN_MAX
常量的系统上工作 [perl #87740]。
#line 42 foo
指令在字符串 eval 中使用时,以前不会更新调试器使用的行数组。这在 5.14 中得到了部分修复,但它只对每个 eval 中的单个 #line 42 foo
有效。现在它对多个有效。
当子例程调用被调试器拦截时,子例程的名称或对它的引用将存储在 $DB::sub
中,供调试器访问。有时(例如 $foo = *bar; undef *bar; &$foo
)$DB::sub
将被设置为一个无法用于查找子例程的名称,因此调试器尝试调用它将失败。现在检查是否需要引用的方法更加健壮,因此这些问题应该不会再发生 [rt.cpan.org #69862]。
每个子例程都与一个文件名相关联,调试器使用该文件名。与常量子例程相关联的文件名在线程下克隆时被错误分配。因此,调试线程应用程序可能会导致内存损坏 [perl #96126]。
defined(${"..."})
、defined(*{"..."})
等,以前对大多数内置变量返回 true,但如果它们尚未使用,则不返回 true。此错误影响 ${^GLOBAL_PHASE}
和 ${^UTF8CACHE}
等。如果也给出了包名(${"::!"}
),它以前也会返回 false [perl #97978, #97492]。
Perl 5.10.0 引入了类似的错误:defined(*{"foo"})
,其中 "foo" 代表内置全局变量的名称,如果该变量以前从未使用过,则返回 false,但仅在第一次调用时返回 false。这也已修复。
从 5.6.0 开始,*{ ... }
在处理未定义值方面一直不一致。它在严格模式或左值上下文中对大多数未定义值会抛出异常,但对 undef()
返回的特定标量(内部为 &PL_sv_undef
)会将其视为空字符串(并发出警告)。这已得到纠正。undef()
现在像其他未定义标量一样被处理,就像在 Perl 5.005 中一样。
Perl 有一个内部变量,用于存储最后访问的文件句柄。它被 $.
以及没有参数的 tell
和 eof
使用。
以前可以将此内部变量设置为一个 glob 复制,然后修改该 glob 复制使其成为除 glob 之外的其他内容,并且在再次为其分配一个 glob 后,仍然将最后访问的文件句柄与该变量相关联。
my $foo = *STDOUT; # $foo is a glob copy
<$foo>; # $foo is now the last-accessed handle
$foo = 3; # no longer a glob
$foo = *STDERR; # still the last-accessed handle
现在 $foo = 3
赋值会取消设置该内部变量,因此没有最后访问的文件句柄,就像 <$foo>
从未发生过一样。
这也防止了某些无关的句柄在 $foo 超出范围并且相同的内部 SV 用于另一个句柄时成为最后访问的句柄 [perl #97988]。
5.14 中的回归导致这些语句没有设置该内部变量。
my $fh = *STDOUT;
tell $fh;
eof $fh;
seek $fh, 0,0;
tell *$fh;
eof *$fh;
seek *$fh, 0,0;
readline *$fh;
这现在已修复,但 tell *{ *$fh }
仍然存在问题,目前尚不清楚如何修复它 [perl #106536]。
stat
术语 "文件测试" 指的是由连字符后跟单个字母组成的运算符:-r
、-x
、-M
等。术语 "堆叠" 当应用于文件测试时,表示后面跟着另一个共享相同操作数的文件测试运算符,如 -r -x -w $fooo
。
stat
现在产生更一致的警告。它不再对 "_" 产生警告 [perl #71002],并且不再偶尔跳过对其他未打开句柄的警告。当操作系统的 fstat
函数失败时,它不再警告未打开的句柄。
stat
有时会对大型 inode 编号返回负数,因为它使用了错误的内部 C 类型。[perl #84590]
lstat
的文档说明,当给定文件句柄时,它会回退到 stat
(并发出警告)。当传递一个 IO 引用时,它实际上执行了等效于 stat _
的操作,并忽略了句柄。
-T _
在没有前导 stat
的情况下,曾经会产生一个令人困惑的“未初始化”警告,即使没有可见的未初始化值。
-T
、-B
、-l
和 -t
现在可以与其他文件测试运算符一起使用 [perl #77388]。
在 5.14.0 中,文件测试运算符 (-r
、-x
等) 开始在列表运算符的先前参数所属的绑定参数上调用 FETCH,如果使用裸字参数或根本没有参数调用。此问题已修复,因此 push @foo, $tied, -r
现在不再在 $tied
上调用 FETCH。
在 Perl 5.6 中,-l
后面跟着除裸字以外的任何内容,都会将其参数视为文件名。这在 5.8 中针对 glob 引用 (\*foo
) 进行了更改,但没有针对 glob 本身 (*foo
) 进行更改。-l
开始对 glob 引用返回 undef
,而没有设置 "_" 句柄使用的最后一个 stat 缓冲区,但前提是启用了警告。如果禁用警告,则与 5.6 相同。换句话说,它只是有错误且不一致。现在,已恢复 5.6 的行为。
-l
后面跟着一个裸字不再“吞噬”它所在的列表运算符参数列表中的前一个参数。因此,print "bar", -l foo
现在实际上会打印 "bar",因为 -l
不再吞噬它。
Perl 保留几个内部变量来跟踪最后一个 stat 缓冲区,它来自哪个文件(句柄),它的类型是什么,以及最后一个 stat 是否成功。
在各种情况下,这些变量可能会不同步,导致边缘情况下的行为不一致或不稳定(所有提到 -T
的地方也适用于 -B
)。
-T HANDLE
即使执行了 stat
,也没有重置最后一个 stat 类型,因此后面的 lstat _
会愉快地返回错误的结果。此外,它也没有设置成功状态。
释放 stat
或文件测试最后使用的句柄会导致 -T _
使用一个无关的句柄。
使用 IO 引用进行 stat
不会重置 stat 类型或记录文件句柄,以便 -T _
使用。
致命警告可能导致文件测试操作符在未打开的文件句柄或任何句柄上的-l
上,不会重置状态缓冲区。致命警告还阻止了-T
设置$!
。
当最后一个状态位于不可读文件上时,-T _
应该返回undef
,保持最后一个状态缓冲区不变。但它正在设置状态类型,导致lstat _
停止工作。
-T FILENAME
没有为不可读文件重置内部状态缓冲区。
这些问题都已修复。
格式和formline
的几个边缘情况已修复;特别是当格式本身可能发生变化时(例如使用绑定和重载),以及当格式和数据在编码方面有所不同时。在这两种情况下,输出以前可能会损坏 [perl #91032]。
formline
不再就地将它的参数转换为字符串。因此,将引用传递给formline
不再破坏引用 [perl #79532]。
对$^A
(格式输出累加器)的赋值现在会重新计算输出的行数。
given
和 when
given
没有正确地对它的隐式$_进行作用域,导致内存泄漏或“变量不可用”警告 [perl #94682]。
given
没有在它使用的隐式词法$_
上调用设置魔法。这意味着,例如,pos
将从同一个given
块的每次执行中记住,即使输入是不同的变量 [perl #84526]。
when
块现在能够返回在封闭的given
块中声明的变量 [perl #93548]。
glob
运算符在除 VMS 之外的操作系统上,Perl 的glob
运算符(以及<...>
形式)在内部使用File::Glob。 File::Glob 将模式拆分为单词,然后将每个单词馈送到它的bsd_glob
函数。
拆分方式存在一些不一致。现在,引号(' 和 ")始终被视为 shell 样式的单词分隔符(允许空格作为单词的一部分),并且反斜杠始终保留,除非它们用于转义引号。以前,只有在模式包含空格时才会出现这种情况。此外,模式末尾的转义空格不再被剥离 [perl #40470]。
CORE::glob
现在作为一种调用默认全局函数的方式。它以前会尊重覆盖,尽管有CORE::
前缀。
在 miniperl(用于在构建 perl 本身时配置模块)下,glob
现在在调用 csh 之前清除 %ENV,因为如果它不喜欢 LS_COLORS 环境变量的内容,后者会在某些系统上报错 [perl #98662]。
显式返回现在返回传递给返回的实际参数,而不是复制它 [perl #72724, #72706]。
Lvalue 子例程用于强制执行 lvalue 语法(即,任何可以在 =
左侧使用的内容)用于最后一个语句和返回参数。由于 lvalue 子例程并不总是以 lvalue 上下文调用,因此此限制已解除。
Lvalue 子例程对返回值的限制较少。它过去会对 shift
和 delete
返回的值以及其他子例程返回的值发出警告,但现在不再这样做 [perl #71172]。
空 lvalue 子例程(sub :lvalue {}
)过去会在列表上下文中返回 @_
。所有子例程过去都这样做,但在 Perl 5.8.2 中,常规子例程已修复。现在,lvalue 子例程也已修复。
自动创建现在适用于从 lvalue 子例程返回的值 [perl #7946],就像在 lvalue 上下文中返回 keys
一样。
Lvalue 子例程过去会在 rvalue 上下文中复制其返回值。这不仅浪费了 CPU 周期,而且还会导致错误。($)
原型会导致 lvalue 子例程复制其返回值 [perl #51408],而 while(lvalue_sub() =~ m/.../g) { ... }
会无限循环 [perl #78680]。
当在潜在的 lvalue 上下文中调用时(例如,子例程参数或传递给 for
的列表),lvalue 子例程过去会复制任何返回的只读值。例如, sub :lvalue { $] }
不会返回 $]
,而是返回它的副本。
当在潜在的 lvalue 上下文中调用时,返回数组或哈希的 lvalue 子例程过去会将数组或哈希绑定到标量变量,从而导致错误。如果数组是子例程返回的第一个内容,则在 5.14.0 中已修复此问题(但不适用于 $scalar, @array
或返回的哈希)。现在已应用更通用的修复程序 [perl #23790]。
所有参数都用 my()
或 our()
包裹(如 $object->method(my($a,$b))
)的方法调用过去会强制在子例程上使用 lvalue 上下文。这将阻止 lvalue 方法返回某些值。
在编译时未确定为 lvalue 的 lvalue 子例程调用(&$name
或 &{"name"})不再免受严格引用,如果它们出现在 lvalue 子例程的最后一个语句中 [perl #102486]。
如果子例程调用在编译时不可见,如果它们出现在 lvalue 子例程的最后一个语句中,则会拒绝非 lvalue 子例程并使用“无法修改非 lvalue 子例程调用”错误退出 [perl #102486]。
在编译时可见的非左值子例程调用,其子例程是可见的,表现出相反的错误。如果调用发生在左值子例程的最后一个语句中,则在左值上下文中调用左值子例程时不会出现错误。Perl 会盲目地将非左值子例程返回的临时值赋值给它。
AUTOLOAD
例程用于优先于实际被调用的子例程(即,当不需要自动加载时),对于左值或潜在左值上下文中子例程的调用,如果子例程在编译时不可见。
在 Perl 5.12 中,将 :lvalue
属性应用于 XSUB 或使用 sub foo :lvalue;
语法别名子例程存根不再起作用。这个问题已修复。
将 :lvalue
属性应用于已定义的子例程不起作用,因为该属性会改变子例程的编译方式。因此,Perl 5.12 在尝试将该属性应用于已定义的子例程时开始发出警告。在这种情况下,该属性将被丢弃。
但是,5.12 中的更改错过了自定义属性也存在的情况:这种情况仍然会默默地且无效地应用该属性。现在已纠正了该遗漏。sub foo :lvalue :Whatever
(当 foo
已定义时)现在会对 :lvalue
属性发出警告,并且不会应用它。
已修复影响通过嵌套左值子例程调用传播左值上下文的错误。以前,在嵌套右值上下文中返回值将被内部子例程调用视为左值上下文,导致某些值(例如只读值)被拒绝。
涉及依赖于 'nomethod' 覆盖的重载对象的算术赋值($left += $right
)当左操作数未重载时不再出现段错误。
在重载期间找不到方法时发生的错误现在会提到正确的包名,就像在 5.8.x 中一样,而不是像从 5.10.0 开始那样错误地提到 "overload" 包。
取消定义 %overload::
不会再导致崩溃。
prototype
函数不再对 __FILE__
、__LINE__
和 __PACKAGE__
指令执行 die 操作。它现在为它们返回一个空字符串原型,因为它们在语法上与 time
等零元函数没有区别。
prototype
现在为所有可覆盖的中缀运算符(例如 eq
)返回 undef
,这些运算符无法以任何类似函数的方式调用。它过去曾为某些运算符返回不正确的原型,而为其他运算符执行 die 操作 [perl #94984]。
几个内置函数的原型——getprotobynumber
、lock
、not
和 select
——已得到修正,或者至少现在比以前更接近现实。
/[[:ascii:]]/
和 /[[:blank:]]/
现在在平台支持的情况下,在 use locale
下使用区域设置规则。以前,它们使用平台的原生字符集。
m/[[:ascii:]]/i
和 /\p{ASCII}/i
现在匹配相同(当不在不同的区域设置下时)。这修复了 5.14 中引入的回归,其中第一个表达式可以匹配 ASCII 范围之外的字符,例如 KELVIN SIGN。
/.*/g
有时会拒绝匹配以 "\n" 结尾的字符串的结尾。这已修复 [perl #109206]。
从 5.12.0 开始,Perl 过去在将 ${ qr// }
分配给哈希元素并使用 Hash::Util 锁定它之后,会将其内部簿记搞乱。这会导致双重释放、崩溃或不稳定行为。
新的(在 5.14.0 中)正则表达式修饰符 /a
当重复使用像 /aa
一样时,禁止在 /i
下匹配范围内的字符的 ASCII 范围之外的字符。这在某些情况下不起作用,所有这些都涉及交替,例如
"\N{KELVIN SIGN}" =~ /k|foo/iaa;
不适当地成功了。这现在已修复。
5.14.0 在正则表达式字符类(如 [\w\s]
)中引入了一些内存泄漏,这些内存泄漏现已修复。(5.14.1)
正则表达式匹配中的边缘情况可能会导致循环。这仅在 /i
下发生,在具有多字符折叠的括号字符类中,以及要匹配的目标字符串包含折叠的第一部分,后跟另一个具有以折叠的剩余部分开头的多字符折叠的字符,再加上一些其他字符。
"s\N{U+DF}" =~ /[\x{DF}foo]/i
就是一个这样的例子。\xDF
折叠为 "ss"
。(5.14.1)
在某些情况下,正则表达式模式匹配中的几个字符没有正确匹配,所有这些都涉及 /i
。受影响的字符是:COMBINING GREEK YPOGEGRAMMENI、GREEK CAPITAL LETTER IOTA、GREEK CAPITAL LETTER UPSILON、GREEK PROSGEGRAMMENI、GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA、GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS、GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA、GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS、LATIN SMALL LETTER LONG S、LATIN SMALL LIGATURE LONG S T 和 LATIN SMALL LIGATURE ST。
修复了线程下正则表达式编译中的内存泄漏回归。
修复了 5.14.0 中引入的回归。这涉及到正则表达式中一个反转的方括号字符类,它只包含一个 Unicode 属性。该属性在 Latin1 范围之外没有被反转。
三个有问题的 Unicode 字符现在在 /i
下的正则表达式模式匹配中工作得更好。
过去,三个 Unicode 字符:LATIN SMALL LETTER SHARP S、GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS 和 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS,以及它们折叠到的序列(包括 LATIN SMALL LETTER SHARP S 的 "ss"),在 /i
下没有正确匹配。5.14.0 修复了其中一些情况,但也引入了其他情况,包括当其中一个字符或序列在 (?(DEFINE)
正则表达式谓词中使用时出现恐慌。5.14 中引入的已知错误现已修复;以及一些以前从未起作用的其他边缘情况。这些都涉及在 /i
下使用方括号字符类之外的字符和序列。这关闭了 [perl #98546]。
在方括号字符类中使用某些具有多字符折叠的字符时,仍然存在已知问题,包括 qr/[\N{LATIN SMALL LETTER SHARP}a-z]/i
等结构。这些剩余的错误在 [perl #89774] 中得到解决。
RT #78266:自 5.10 引入命名捕获以来,正则表达式引擎在访问未匹配为正则表达式一部分的命名捕获时一直存在内存泄漏;例如,这将消耗超过 100 MB 的内存。
for (1..10_000_000) {
if ("foo" =~ /(foo|(?<capture>bar))?/) {
my $capture = $+{capture}
}
}
system "ps -o rss $$"'
在 5.14 中,/[[:lower:]]/i
和 /[[:upper:]]/i
不再匹配相反的大小写。这已修复 [perl #101970]。
使用右侧的重载对象的正则表达式匹配有时会对对象进行多次字符串化。
修复了在 5.14 中引入的回归,在 /i
正则表达式匹配中,如果模式为 UTF-8,目标字符串不是,并且 Latin-1 字符位于字符串中应该匹配模式的字符之前,则匹配会错误地失败。[perl #101710]
在不区分大小写的正则表达式模式匹配中,不再对 UTF-8 编码的字符串进行扫描,以查找匹配的开始位置,只查看第一个可能的位置。这会导致 "f\x{FB00}" =~ /ff/i
等匹配失败。
正则表达式优化器在调试版本中不再在合并具有不方便内容的固定字符串节点时崩溃。
在 5.14.0 中引入的正则表达式修饰符 /aa
和转义序列 \b
的组合导致的恐慌问题已修复 [perl #95964]。(5.14.2)
正则表达式修饰符 /aa
与转义序列 \b
和 \B
的组合在 UTF-8 编码字符串上无法正常工作。在 /aa
下,所有非 ASCII 字符都应被视为非单词字符,但实际情况是,Unicode 规则被用于确定非 ASCII 字符的单词/非单词属性。此问题现已修复 [perl #95968]。
(?foo: ...)
现在不再丢失传入的字符集。
用于优化 Trie 的方法在包含空 (?:)
的交替中存在问题,导致 "x" =~ /\A(?>(?:(?:)A|B|C?x))\z/
无法匹配,而它应该匹配 [perl #111842]。
在正则表达式中嵌入的代码块中使用词法(my
)变量将不再导致内存损坏或崩溃。
尽管如此,这些代码块仍然处于实验阶段,因为在闭包(例如循环中)和异常退出(例如 die
)时,仍然存在错误变量闭包和内存损坏问题。
正则表达式元字符 \h
、\H
、\v
和 \V
在尝试匹配字符串末尾时会导致恐慌错误消息 [perl #96354]。
之前,\N{}
、vianame() 和 string_vianame() 无法识别四个 C1 控制字符 MW
、PM
、RI
和 ST
的缩写。
除了 $&
之外,提及名为 "&" 的变量(例如 @&
或 %&
)不再阻止 $&
工作。同样适用于名为 "'" 和 "`" 的变量 [perl #24237]。
创建 UNIVERSAL::AUTOLOAD
子例程不再阻止 %+
、%-
和 %!
在某些情况下工作 [perl #105024]。
~~
现在正确处理 Any~~Object 的优先级,并且不会被左侧的重载对象欺骗。
在 Perl 5.14.0 中,$tainted ~~ @array
停止正常工作。有时它会错误地失败(当 $tainted
包含一个出现在数组中第一个元素之后的字符串时)或错误地成功(当 undef
出现在第一个元素之后时) [perl #93590]。
sort
运算符当提供这样的子例程作为比较例程时,sort
不会将 sub {}
和 sub {()}
视为等效。它以前会在 sub {()}
上崩溃。
sort
现在可以再次使用作为 XSUB 的自定义排序例程。它在 5.10.0 中停止工作。
使用常量作为自定义排序例程的 sort
虽然会产生未排序的结果,但不再崩溃。它在 5.10.0 中开始崩溃。
当自定义比较例程返回非数值时,sort
发出的警告现在包含“in sort”,并显示sort
运算符的行号,而不是比较例程的最后一行。这些警告现在也只在sort
发生的作用域中启用了警告时才会发生。以前,如果在比较例程的作用域中启用了警告,则会发生警告。
sort { $a <=> $b }
在内部进行了优化,现在会对 NaN(非数字值)产生“未初始化”警告,因为<=>
对这些值返回undef
。这使其与 sort { 1; $a <=> $b }
和其他更复杂的情况保持一致,这些情况没有被优化 [perl #94390]。
substr
运算符绑定(和其他神奇)变量不再免于“尝试将引用用作 substr 中的左值”警告。
该警告现在发生在返回的左值被赋值时,而不是在substr
本身被调用时。这只有在substr
的返回值被引用并在以后被赋值时才会产生差异。
将只读值的子字符串或类型全局变量传递给函数(潜在的左值上下文)不再会导致立即出现“无法强制转换”或“修改只读值”错误。该错误只有在传递的值被赋值时才会发生。
对于“字符串之外的 substr”错误也是如此。如果左值只被读取,而不是写入,它现在只是一个警告,就像右值substr
一样。
如果第一个参数是绑定变量,substr
赋值不再调用两次 FETCH,而只调用一次。
Perl 的某些部分在处理字符串中嵌入的空字符 (chr 0
) 时无法正常工作。这意味着,例如,$m = "a\0b"; foo->$m
会调用“a”方法,而不是$m
中包含的实际方法名称。这些 Perl 部分已修复以支持空字符。
方法名称
类型全局变量名称(包括文件句柄和子程序名称)
包名称,包括ref()
的返回值
类型全局变量元素 (*foo{"THING\0stuff"}
)
信号名称
各种提及变量名或值、方法等的警告和错误消息。
这些更改的一个副作用是,祝福到“\0”不再导致ref()
返回 false。
如果父线程已经有一个具有相同名称的全局变量,则不再克隆从线程返回的类型全局变量。这意味着返回的子程序现在将分配到正确的包变量 [perl #107366]。
已修复一些由于克隆期间内存分配导致线程崩溃的情况 [perl #90006]。
如果在创建线程之前从DB
包中使用了caller
,线程连接有时会发出“尝试释放未引用的标量”警告 [perl #98092]。
锁定子例程(通过 `lock &sub`)不再是常规子例程的编译时错误。对于左值子例程,它不再尝试将子例程作为标量返回,从而导致奇怪的副作用,例如在某些情况下 `ref \$_` 返回 "CODE"。
如果加载了 threads::shared,`lock &sub` 现在是运行时错误(否则为无操作),但这可能会在将来的版本中得到纠正。
已修复 FETCH 被忽略或调用次数过多的各种情况
PerlIO::get_layers
[perl #97956]
$tied =~ y/a/b/
、chop $tied
和 chomp $tied
,当 $tied 持有引用时。
调用 local $_
时 [perl #105912]
四参数 `select`
传递给 `sysread` 的绑定缓冲区
$tied .= <>
三参数 `open`,第三个参数是绑定文件句柄(如 `open $fh, ">&", $tied`)
使用绑定全局变量的引用作为比较例程的 `sort`。
列表上下文中 `..` 和 `...` [perl #53554]。
${$tied}
、@{$tied}
、%{$tied}
和 *{$tied}
,其中绑定变量返回字符串(`&{}` 未受影响)
defined ${ $tied_variable }
各种在右值上下文中接受文件句柄参数的函数(`close`、`readline` 等)[perl #97482]
对复杂表达式的解引用的一些情况,例如 `${ (), $tied } = 1`,过去会多次调用 `FETCH`,但现在只调用一次。
$tied->method
,其中 $tied 返回包名——即使导致无法调用方法,也会导致内存损坏
类似于 `*$tied = \&{"..."}` 和 `*glob = $tied` 的赋值
chdir
、chmod
、chown
、utime
、truncate
、stat
、lstat
和文件测试操作(`-r`、`-x` 等)
当从 DB 包中调用时,`caller` 将 `@DB::args` 设置为子例程参数。如果 `@DB::args` 碰巧被绑定,它过去会崩溃。现在它会抛出异常。
绑定 %ENV 或 `%^H` 的元素,然后删除该元素会导致调用绑定对象的 DELETE 方法,即使绑定元素本身应该等同于绑定标量(元素当然是一个标量)[perl #67490]。
当 Perl 自动创建绑定数组或哈希的元素(这需要使用新引用调用 STORE)时,它现在会在 STORE 之后立即调用 FETCH,而不是假设 FETCH 会返回相同的引用。这可以使绑定对象的实现更容易 [perl #35865, #43011]。
四参数 `select` 在绑定或被污染的变量(它们是字符串)上不再产生其 "Non-string passed as bitmask" 警告。
局部化返回类型全局变量的绑定标量不再阻止它在作用域结束之前被绑定。
尝试从绑定的句柄方法中goto
出去会导致内存损坏或崩溃。现在它会产生错误消息而不是[perl #8611]。
已修复在使用绑定变量作为子例程引用时发生的错误:如果最后分配给变量或从变量返回的是引用或类型全局,则\&$tied
可能会崩溃或返回错误的子例程。引用情况是在 Perl 5.10.0 中引入的回归。对于类型全局,它可能从未正常工作过。
当传递 vstring 时,按位取反运算符(以及可能的其他运算符)会将 vstring 魔法附加到返回值,即使字符串已更改。这意味着version->new(~v1.2.3)
将创建一个看起来像“v1.2.3”的版本,即使传递给version->new
的字符串实际上是“\376\375\374”。这也导致B::Deparse错误地解析~v1.2.3
,没有~
[perl #29070]。
将 vstring 分配给魔法(例如,绑定,$!
)变量,然后分配其他内容会清除所有魔法。这意味着绑定变量将被取消,$!
将停止在系统调用失败时更新,$|
将停止设置自动刷新,以及其他恶作剧将发生。这已修复。
version->new("version")
和printf "%vd", "version"
不再崩溃 [perl #102586]。
版本比较,例如use v5.43
中隐式发生的比较,不再导致区域设置更改 [perl #105784]。
版本对象不再在布尔上下文中导致内存泄漏 [perl #109762]。
来自autouse
命名空间的子例程再次免于重新定义警告。这曾经在 5.005 中有效,但在 5.6 中对于大多数子例程被破坏。对于通过 XS 创建的重新定义来自autouse
包的子例程的子例程,这在 5.10 中停止工作。
新的 XSUB 现在会在覆盖现有子例程时产生重新定义警告,就像它们在 5.8.x 中一样。(autouse
逻辑在 5.10-14 中被反转。只有来自autouse
命名空间的子例程在被覆盖时会发出警告。)
newCONSTSUB
曾经使用编译时警告提示,而不是运行时提示。以下代码永远不会产生重新定义警告,但如果newCONSTSUB
重新定义了现有子例程,它曾经会产生警告
use warnings;
BEGIN {
no warnings;
some_XS_function_that_calls_new_CONSTSUB();
}
默认情况下,常量子例程的重新定义警告是开启的(在 perldiag 中被称为严重警告)。这仅在它是导致警告的 glob 赋值或 Perl 子例程声明时才会发生。如果 XSUB 的创建触发了警告,则它不是默认警告。此问题已得到修复。
用于检查是否应该发生重新定义警告的内部检查过去会在以下情况下发出“未初始化”警告
use warnings "uninitialized";
use constant {u => undef, v => undef};
sub foo(){u}
sub foo(){v}
各种在右值上下文中接受文件句柄参数的函数(close
、readline
等)过去会对未定义的句柄发出两次警告 [perl #97482]。
dbmopen
现在仅在模式参数为 undef
时发出一次警告,而不是三次 [perl #90064]。
+=
运算符通常在左侧为 undef
时不会发出警告,但它在绑定变量时会发出警告。此问题已得到修复 [perl #44895]。
Perl 5.14 中的一个错误修复引入了一个新错误,导致“未初始化”警告在所讨论的运算符具有两个操作数且其中一个为 %{...}
或 @{...}
时报告错误的变量。此问题已得到修复 [perl #103766]。
列表上下文中 ..
和 ...
现在在字符串(而不是数字)范围的“未初始化”警告中提及变量的名称。
削弱自动调用 DESTROY
方法的第一个参数可能会导致错误的“DESTROY 创建了新引用”错误或崩溃。现在,削弱只读引用是一个错误。
对即将超出范围的词法哈希的弱引用不会失效(变为未定义),而是继续指向该哈希。
对即将超出范围的词法变量的弱引用现在会在任何神奇方法(例如,绑定对象上的 DESTROY)被调用之前被破坏。这可以防止这些方法修改在下次进入范围时将看到的变量。
创建对 @ISA 数组的弱引用或访问数组索引 ($#ISA
) 可能会导致对稍后添加到 @ISA 数组的元素的内部簿记混乱。例如,创建对元素本身的弱引用可能会将该弱引用推送到 @ISA 上;并且在使用 $#ISA
后添加的元素将被方法查找忽略 [perl #85670]。
quotemeta
现在在 use feature 'unicode_strings'
下一致地引用相同的非 ASCII 字符,无论字符串是否以 UTF-8 编码,从而修复了臭名昭著的 "perlunicode 中的“Unicode 错误”" 的最后遗留问题(我们希望如此)。[perl #77654]。
根据 Unicode 的建议,引用了哪些代码点发生了变化。有关详细信息,请参阅 "perlfunc 中的 quotemeta"。
study
现在是一个空操作,可能修复了所有与 study 导致正则表达式匹配行为不正确相关的未解决错误!
当编写 open foo || die
时,这在 Perl 4 中曾经有效,会产生“优先级问题”警告。此警告错误地应用于不带 ||
的完全限定的裸字句柄名称。这已得到纠正。
在包别名(*foo:: = *bar::
)之后,select
具有 0 或 1 个参数有时会返回一个无法用于引用文件句柄的名称,或者有时它会返回 undef
,即使选择了文件句柄。现在,在这种情况下,它返回一个类型全局引用。
PerlIO::get_layers
不再忽略它认为是数字的一些参数,同时将其他参数视为文件句柄名称。现在它对扁平标量(即非引用)是一致的。
#!
行上的无法识别的开关
如果在 #!
行上使用了无法出现在该行上的开关,例如 -x,perl 会因“无法模拟...”而死亡。
它过去会对 perl 完全无法识别的开关产生相同的错误消息,无论是在命令行还是在 #!
行上。
现在它会产生“无法识别的开关”错误消息 [perl #104288]。
system
现在暂时阻塞 SIGCHLD 信号处理程序,以防止信号处理程序窃取退出状态 [perl #105700]。
printf
和 sprintf
的 %n 格式化代码会导致字符数被分配给下一个参数,现在实际上分配了字符数,而不是字节数。
它现在也适用于像 substr
这样的特殊左值函数以及不存在的哈希和数组元素 [perl #3471, #103492]。
为了速度起见,Perl 跳过复制从子例程返回的值,如果这样做不会产生可观察到的差异。由于逻辑错误,这将发生在 delete
、shift
或 splice
的结果上,即使结果在其他地方被引用。它也对即将被释放的绑定变量执行此操作 [perl #91844, #95548]。
utf8::decode
现在拒绝修改只读标量 [perl #91850]。
在 grep
或 map
块、嵌入正则表达式的代码块或 @INC 过滤器(@INC 中子程序返回的子程序)中释放 $_ 以前会导致双重释放或崩溃 [perl #91880, #92254, #92256]。
当出现运行时错误时,eval
在标量上下文中返回 undef
,在列表上下文中返回空列表。当 eval
在列表上下文中传递一个字符串并发生语法错误时,它以前会返回一个包含单个未定义元素的列表。现在它在所有错误的列表上下文中返回一个空列表 [perl #80630]。
当当前子程序作用域的展开触发一个将要“goto”的子程序取消定义的析构函数时,goto &func
不再崩溃,而是产生错误消息 [perl #99850]。
Perl 现在对当前正在编译的包保持额外的引用计数。这意味着以下代码不再崩溃 [perl #101486]。
package Foo;
BEGIN {*Foo:: = *Bar::}
sub foo;
x
重复运算符在 64 位构建中不再对大型重复计数崩溃 [perl #94560]。
当 *CORE::GLOBAL::require
被覆盖时,在隐式 $_
上调用 require
不再导致段错误,并且 $_
现在被传递给覆盖的子程序 [perl #78260]。
use
和 require
不再受调用者作用域中激活的 I/O 层的影响(由 open.pm 启用) [perl #96008]。
our $::é; $é
(无效)不再产生“Compilation error at lib/utf8_heavy.pl...”错误消息,它在 5.10.0 中开始发出 [perl #99984]。
在 64 位系统上,read()
现在理解超过 32 位范围的大字符串偏移量。
处理子程序属性时发生的错误不再导致子程序的操作树泄漏。
将相同的常量子程序传递给 index
和 formline
不再导致其中一个失败 [perl #89218]。(5.14.1)
在同一语句中声明具有属性的词法变量的列表赋值(my ($x,@y) : blimp = (72,94)
)在 Perl 5.8.0 中停止工作。现在已修复。
Perl 5.10.0 引入了一些错误的逻辑,导致如果输入字符串为空,则 pack 模板中间的“U*”等效于“U0”。这已修复 [perl #90160]。(5.14.2)
在全局销毁期间,对未被任何标量引用的对象,其析构函数不会被调用。这种情况可能发生在数组元素被祝福(例如,bless \$a[0]
)或闭包引用了被祝福的变量(bless \my @a; sub foo { @a }
)时。
现在,在全局销毁期间增加了一个额外的步骤,用于触发对任何可能在检查标量引用的对象的常规步骤之后剩余对象的析构函数 [perl #36347]。
修复了在解析 here 文档时,可能从已释放的缓冲区读取数据的错误 [perl #90128]。(5.14.1)
each(ARRAY)
现在被包装在 defined(...)
中,类似于 each(HASH)
,位于 while
条件内部 [perl #90888]。
修复了当 do
块作为 return
的参数时,上下文传播的问题。它曾经会导致在 if
块内部的 return
之后紧跟着另一个 return
的情况下,返回 undef
。
使用被污染的常量调用 index
不会再导致随后编译的代码中的常量被污染 [perl #64804]。
像 1 while 1
这样的无限循环曾经会阻止 strict 'subs'
模式对块的其余部分生效。
对于像 ($a,$b) = ($b,$a)
这样的列表赋值,Perl 必须在将右侧的项赋值给左侧之前,先复制右侧的项。为了效率起见,如果两侧都没有变量被提及,例如 ($a,$b) = ($c,$d)
,它会直接将右侧的值赋值给左侧的项。确定何时可以作弊的逻辑存在缺陷,因为右侧的 &&
和 ||
会欺骗它。因此,($a,$b) = $some_true_value && ($b,$a)
最终会将 $b
的值赋值给两个标量。
Perl 现在不再尝试将左值上下文应用于 ("string", $variable) ||= 1
中的字符串(以前会导致错误)。由于 ||=
左侧在标量上下文中进行评估,因此这是一个标量逗号运算符,它会将除最后一个项目之外的所有项目置于空上下文。由于不存在空左值上下文,因此 Perl 尝试强制执行它是一个错误 [perl #96942]。
如果在第一次调用 caller
之后将 @DB::args
赋值,caller
现在不再在从 DB 包调用时泄漏内存。 Carp 触发了此错误 [perl #97010]。(5.14.2)
当在内置全局变量(如 $+
)上调用 close
和类似的文件句柄函数时,如果变量碰巧包含未定义的值,以前会死亡,而不是产生通常的“使用未初始化的值”警告。
当 Perl 5.6.0 中引入自动生成的 文件句柄时,readline
不小心被设置为在作为 readline($foo)
调用时自动生成(但不是作为 <$foo>
调用时)。现在它已修复,永远不会自动生成。
调用未定义的匿名子例程(例如,在 undef &{$x = sub{}}
之后 $x 所持有的内容)以前会导致“不是 CODE 引用”错误,现在已更正为“调用未定义的子例程” [perl #71154]。
在使用 caller
之间导致 @DB::args
被释放不再会导致崩溃 [perl #93320]。
setpgrp($foo)
以前等效于 ($foo, setpgrp)
,因为 setpgrp
如果只有一个参数,则会忽略它的参数。现在它等效于 setpgrp($foo,0)
。
shmread
在从共享内存读取时没有正确设置标量标志,导致标量中现有的缓存数字表示形式持续存在 [perl #98480]。
++
和 --
现在在全局变量的副本上工作,而不是死亡。
splice()
在截断时不会发出警告
现在可以使用 splice(@a,MAX_LEN)
限制数组的大小,而无需担心警告。
$$
不再被污染。由于此值直接来自 getpid()
,因此始终安全。
解析器在解析开始之前 STDIN 被关闭时不再泄漏文件句柄 [perl #37033]。
die;
在 $@ 中使用非引用、非字符串或魔法(例如,污染)值现在会正确传播该值 [perl #111654]。
在 Solaris 上,我们遇到了两种类型的错误。
如果 make 是 Sun 的 make,我们会收到关于 Makefile 中格式错误的宏赋值的错误。这发生在 ./Configure 尝试生成依赖项时。Configure 随后退出 0,但后续的 make 操作会失败。
如果 make 是 gmake,Configure 会完成,然后我们会收到与 /usr/include/stdbool.h 相关的错误。
在 Win32 上,除非重定向 STDERR,否则许多测试会挂起。其原因仍在调查中。
当以 root 身份构建并且 umask 阻止文件被其他用户读取时,t/op/filetest.t 会失败。这是一个测试错误,而不是 Perl 行为中的错误。
使用最新的 gcc 和链接时优化进行配置,例如 Configure -Doptimize='-O2 -flto'
会失败,因为优化器会优化掉 Configure 中的一些测试。解决方法是在运行 Configure 时省略 -flto
标志,但在实际构建时将其添加回来,例如
sh Configure -Doptimize=-O2
make OPTIMIZE='-O2 -flto'
以下 CPAN 模块在 Perl 5.16 中存在测试失败。这些模块都已提交补丁,因此希望很快就会有新的版本发布
Date::Pcalc 版本 6.1
Module::CPANTS::Analyse 版本 0.85
这是由于 Module::Find 0.10 和 File::MMagic 1.27 中的问题导致的。
PerlIO::Util 版本 0.72
Perl 5.16.0 代表了自 Perl 5.14.0 发布以来的大约 12 个月的开发,包含了来自 139 位作者的 2,500 个文件中的大约 590,000 行代码变更。
Perl 凭借其充满活力的用户和开发者社区,在进入其第三个十年后依然蓬勃发展。以下人员已知为 Perl 5.16.0 的改进做出了贡献
Aaron Crane,Abhijit Menon-Sen,Abigail,Alan Haggai Alavi,Alberto Simões,Alexandr Ciornii,Andreas König,Andy Dougherty,Aristotle Pagaltzis,Bo Johansson,Bo Lindbergh,Breno G. de Oliveira,brian d foy,Brian Fraser,Brian Greenfield,Carl Hayter,Chas. Owens,Chia-liang Kao,Chip Salzenberg,Chris 'BinGOs' Williams,Christian Hansen,Christopher J. Madsen,chromatic,Claes Jacobsson,Claudio Ramirez,Craig A. Berry,Damian Conway,Daniel Kahn Gillmor,Darin McBride,Dave Rolsky,David Cantrell,David Golden,David Leadbeater,David Mitchell,Dee Newcum,Dennis Kaarsemaker,Dominic Hargreaves,Douglas Christopher Wilson,Eric Brine,Father Chrysostomos,Florian Ragwitz,Frederic Briere,George Greer,Gerard Goossen,Gisle Aas,H.Merijn Brand,Hojung Youn,Ian Goodacre,James E Keenan,Jan Dubois,Jerry D. Hedden,Jesse Luehrs,Jesse Vincent,Jilles Tjoelker,Jim Cromie,Jim Meyering,Joel Berger,Johan Vromans,Johannes Plunien,John Hawkinson,John P. Linderman,John Peacock,Joshua ben Jore,Juerd Waalboer,Karl Williamson,Karthik Rajagopalan,Keith Thompson,Kevin J. Woolley,Kevin Ryde,Laurent Dami,Leo Lapworth,Leon Brocard,Leon Timmermans,Louis Strous,Lukas Mai,Marc Green,Marcel Grünauer,Mark A. Stratman,Mark Dootson,Mark Jason Dominus,Martin Hasch,Matthew Horsfall,Max Maischein,Michael G Schwern,Michael Witten,Mike Sheldrake,Moritz Lenz,Nicholas Clark,Niko Tyni,Nuno Carvalho,Pau Amma,Paul Evans,Paul Green,Paul Johnson,Perlover,Peter John Acklam,Peter Martini,Peter Scott,Phil Monsen,Pino Toscano,Rafael Garcia-Suarez,Rainer Tammer,Reini Urban,Ricardo Signes,Robin Barker,Rodolfo Carvalho,Salvador Fandiño,Sam Kimbrel,Samuel Thibault,Shawn M Moore,Shigeya Suzuki,Shirakata Kentaro,Shlomi Fish,Sisyphus,Slaven Rezic,Spiros Denaxas,Steffen Müller,Steffen Schwigon,Stephen Bennett,Stephen Oberholtzer,Stevan Little,Steve Hay,Steve Peters,Thomas Sibley,Thorsten Glaser,Timothe Litt,Todd Rinaldo,Tom Christiansen,Tom Hukins,Tony Cook,Vadim Konovalov,Vincent Pit,Vladimir Timofeev,Walt Mankowski,Yves Orton,Zefram,Zsbán Ambrus,Ævar Arnfjörð Bjarmason。
上面的列表几乎肯定是不完整的,因为它是由版本控制历史自动生成的。特别是,它不包括向 Perl 错误跟踪器报告问题的贡献者(非常感谢)的姓名。
此版本中包含的许多更改源自 Perl 核心包含的 CPAN 模块。我们感谢整个 CPAN 社区帮助 Perl 蓬勃发展。
有关 Perl 所有历史贡献者的更完整列表,请参阅 Perl 源代码分发中的 AUTHORS 文件。
如果您发现疑似错误,可以查看最近发布到 comp.lang.perl.misc 新闻组的文章以及 Perl 错误数据库 http://rt.perl.org/perlbug/。您也可以在 Perl 主页 https://www.perl5.cn/ 上找到相关信息。
如果您认为您遇到了未报告的错误,请运行随您的版本一起提供的 perlbug 程序。请确保将您的错误缩减为一个微小但足够的测试用例。您的错误报告以及 perl -V
的输出将被发送到 [email protected],由 Perl 移植团队进行分析。
如果您要报告的错误涉及安全问题,不适合发送到公开存档的邮件列表,请将其发送到 [email protected]。此地址指向一个封闭的订阅未存档邮件列表,其中包括所有核心提交者,他们将能够帮助评估问题的影響,找出解决方案,并帮助协调在所有支持 Perl 的平台上发布补丁以减轻或修复问题。请仅将此地址用于 Perl 核心中的安全问题,不要用于 CPAN 上独立分发的模块。
Changes 文件,了解如何查看有关更改的详尽信息。
INSTALL 文件,了解如何构建 Perl。
README 文件,了解一般信息。
Artistic 和 Copying 文件,了解版权信息。