perl5360delta - perl v5.36.0 的新功能
本文档描述了 5.34.0 版本和 5.36.0 版本之间的差异。
use v5.36
与往常一样,use v5.36
会开启该 Perl 版本的功能包。
5.36 包启用了 signatures
功能。该功能在 Perl 5.20.0 版本中引入,并自此进行了多次修改,现在不再被视为实验性功能。它现在被视为稳定的语言功能,不再发出警告。
use v5.36;
sub add ($x, $y) {
return $x + $y;
}
尽管如此,签名子例程的某些元素仍然是实验性的;请参见下文。
5.36 包启用了 isa
功能。该运算符在 Perl 5.32.0 版本中引入,自此保持不变。该运算符现在被视为稳定的语言功能。有关更多详细信息,请参见 "perlop 中的类实例运算符"。
5.36 包还禁用了indirect
和 multidimensional
功能。这些功能将分别禁止:使用“间接”方法调用(如 $x = new Class;
);使用列表表达式作为哈希键来模拟稀疏多维数组。这些更改的具体细节可以在 feature 中找到,但简而言之:这有点像开启了更多 use strict
,禁用了比其价值更多麻烦的功能。
此外,use v5.36
还将启用警告,就像您编写了 use warnings
一样。
最后,在本版本中,自 v5.10 中引入功能包以来,每个功能包中都存在的实验性 switch
功能已从 v5.36 包中删除。如果您想使用它(不建议这样做),您需要显式启用它。
提供了一个新的命令行标志 -g。它是 -0777 的简化别名。
有关更多信息,请参见 "perlrun 中的 -g"。
有关详细信息,请参见 https://www.unicode.org/versions/Unicode14.0.0/。
在此版本之前,正则表达式集合功能(正式名称为“扩展括号字符类”)被视为实验性功能。该功能在 Perl 5.18.0 版本中引入,并自那时起进行了多次修改,现在被认为是稳定的语言功能,其使用不再发出警告。请参阅 "perlrecharclass 中的扩展括号字符类"。
在此版本之前,任何形式的可变长度后顾之忧都被视为实验性功能。在此版本中,实验性状态已缩减至仅涵盖包含捕获括号的后顾之忧。这是因为尚不清楚
"aaz"=~/(?=z)(?<=(a|aa))/
应该匹配并使 $1 等于 "a" 还是 "aa"。目前,它将匹配最长的可能替代方案 "aa"。虽然我们相信该构造现在只会匹配它应该匹配的情况,但我们不确定是否会保留当前的“最长匹配”行为。
浮点异常现在会立即传递,与其他“错误”类信号(如 SIGSEGV)相同。这意味着至少有机会使用 $SIG{FPE}
处理程序捕获此类信号,例如,以便 die
可以报告触发该信号的 perl 代码行。
“true” 和 “false” 布尔值(通常通过 !!0
和 !!1
等构造访问,以及从许多核心函数和运算符返回)现在即使通过赋值到变量也会记住其布尔值性质。新的函数 is_bool()
在 builtin 中可以检查一个值是否具有布尔值性质。
这在与其他语言或数据类型序列化进行交互时可能很有用,以及在其他地方。
您现在可以通过在括号内指定一个词法列表来一次迭代多个值。例如,
for my ($key, $value) (%hash) { ... }
for my ($left, $right, $gripping) (@moties) { ... }
在 perl v5.36 之前,尝试在 for my
之后指定一个列表会导致语法错误。
此功能目前处于实验阶段,将导致类别为 experimental::for_list
的警告。有关更多详细信息,请参阅 "perlsyn 中的复合语句"。另请参阅本文档中的 "builtin::indexed",它是 n-at-a-time foreach 的一个便捷伴侣。
添加了一个新的核心模块 builtin,它提供了对内置于解释器中的新始终存在的函数的文档。
say "Reference type of arrays is ", builtin::reftype([]);
它还提供了一种词法导入机制,用于提供这些函数的简短名称版本。
use builtin 'reftype';
say "Reference type of arrays is ", reftype([]);
此内置函数机制及其提供的函数目前均为实验性。我们预计builtin
本身将在不久的将来不再是实验性的,但其中的各个函数可能会持续稳定。随着时间的推移,将向builtin
添加其他函数。
有关详细信息,请参阅builtin,但以下是 v5.36 中内置函数的摘要
此函数将它的参数视为字符串,返回删除其开头和结尾的所有空格后的结果。
此函数返回一个列表,其大小是其参数列表的两倍,其中每个项目都以其在该列表中的索引为前缀。这主要用于使用新的foreach
语法,使用多个迭代器变量来迭代数组或列表,同时跟踪每个项目的索引
use builtin 'indexed';
foreach my ($index, $val) (indexed @array) {
...
}
true
和 false
返回布尔值 true 和 false。Perl 仍然是 Perl,没有对布尔值的严格类型检查,但这些值将被认为是作为布尔值创建的。is_bool
将告诉您一个值是否被认为是作为布尔值创建的。
这些函数将分别:削弱引用;加强引用;并返回引用是否为弱引用。(弱引用不会计入垃圾回收。请参阅perlref。)这些可以代替Scalar::Util中的某些类似例程。
这些函数提供了有关引用(或非引用,实际上!)的更多数据,并且可以代替Scalar::Util中找到的类似例程。
ceil
返回大于或等于其参数的最小整数。floor
返回小于或等于其参数的最大整数。这些可以代替POSIX中找到的类似例程。
defer
块(实验性)此版本添加了对defer
块的支持,defer
块是代码块,以defer
修饰符为前缀。它们提供了一段代码,该代码将在稍后的时间(在作用域退出期间)运行。
简而言之,当运行时遇到 defer
块时,它的主体会被搁置,并在封闭作用域退出时运行。它与 UNITCHECK 不同(除其他原因外),如果在到达 defer
块之前退出了包含 defer
块的块,则它不会运行。
defer
块可以用来代替“作用域保护”对象,其中一个对象被传递一个代码块,由它的析构函数运行。
有关更多信息,请参见 "perlsyn 中的 defer 块"。
finally
块(实验性)实验性的 try
/catch
语法已扩展为支持由 finally
关键字引入的可选第三个块。
try {
attempt();
print "Success\n";
}
catch ($e) {
print "Failure\n";
}
finally {
print "This happens regardless\n";
}
这提供了在 try
/catch
结构结束时运行的代码,即使被异常或控制流关键字中止。它们类似于 defer
块。
有关更多信息,请参见 "perlsyn 中的 Try Catch 异常处理"。
Perl 传统上只允许四对字符串/模式分隔符:( )
{ }
[ ]
和 < >
,所有都在 ASCII 范围内。Unicode 有数百种可能性,使用此功能可以启用其中许多。启用后,您可以说 qr« »
,例如,或 use utf8; q𝄃string𝄂
。有关详细信息,请参见 "feature 中的 'extra_paired_delimiters' 功能"。
即使子程序签名现在已经稳定,在具有签名的子程序中使用遗留参数数组 (@_
) 仍然是实验性的,有自己的警告类别。静默 experimental::signatures
警告类别不足以消除这一点。新的警告以类别名称 experimental::args_array_with_signatures
发出。
任何具有签名的子程序,如果尝试显式或隐式地使用默认参数数组或其元素 (@_
或 $_[INDEX]
)(例如,没有参数的 shift
或 pop
),都会在编译时引发警告。
use v5.36;
sub f ($x, $y = 123) {
say "The first argument is $_[0]";
}
Use of @_ in array element with signatured subroutine is experimental
at file.pl line 4.
尝试执行此操作的代码的行为不再指定,并且可能会在将来的版本中发生变化。
@a = sort @empty; # unaffected
@a = sort; # now a compile-time error
@a = sort (); # also a compile-time error
以前,一个裸排序是一种创建空列表的奇怪方式;现在它在编译时会报错。此更改旨在为将来可能对 sort
的增强腾出一些语法空间。
use VERSION
(其中 VERSION 低于 v5.11)在 use v5.11
之后已被弃用在 use v5.11
或更高版本的作用域中,use vX
行(其中 X 低于 v5.11)现在会发出警告
Downgrading a use VERSION declaration to below v5.11 is deprecated
例如
use v5.14;
say "The say statement is permitted";
use v5.8; # This will print a warning
print "We must use print\n";
这是因为 Perl 团队计划更改此情况下的行为。从 Perl v5.12(以及 v5.11 的部分内容)开始,strict 处于启用状态,除非它之前已被禁用。换句话说
no strict;
use v5.12; # will not enable strict, because "no strict" preceded it
$x = 1; # permitted, despite no "my" declaration
将来,此行为将被消除,use VERSION
将始终为 v5.12 及更高版本启用 strict。
希望以这种方式混合版本的代码应使用带块语法的词法作用域,以确保不同版本区域在词法上保持隔离。
{
use v5.14;
say "The say statement is permitted";
}
{
use v5.8; # No warning is emitted
print "We must use print\n";
}
当然,这可能不是你真正需要做的事情!如果第一个块编译成功,则意味着你正在使用 perl v5.14.0 或更高版本。
我们现在探测编译器对 C11 线程本地存储的支持,并在可用时将其用于 XS 扩展的“隐式上下文”,这些扩展为线程化的 Perl 构建进行 API 调用。与 POSIX 线程特定存储相比,这在 C 级别的函数调用更少。如果 C11 方法不可用,我们将继续使用 pthreads 方法。
Configure 使用默认值运行将构建一个非线程化的 Perl(速度略快),但大多数操作系统都提供一个线程化的 Perl。
Perl 现在可以配置为不再为大型哈希从共享字符串表中分配键。
相同的内部数据类型 (PVHV
) 用于以下所有内容:
符号表
对象(默认情况下)
关联数组
共享字符串表最初是为了提高用作对象的祝福哈希的性能而添加的,因为每个对象实例都具有相同的键,因此共享它们之间的内存是一种优化。它也适用于符号表,其中派生类将具有相同的键(通常是方法名称),并且为方法调用构建的 OP 树也可以共享内存。共享字符串表的行为大致类似于哈希键的缓存。
但是,对于实际上用作关联数组(将键映射到值)的哈希,通常键不会在其他哈希中重复使用。例如,“已查看”哈希以对象 ID(或地址)为键,从逻辑上讲,这些键不会在其他哈希中重复。
将这些“仅使用一次”的键存储在共享字符串表中会增加 CPU 和 RAM 使用量,而不会带来任何收益。对于此类键,共享字符串表的行为类似于命中率为 0% 的缓存。将所有键存储在那里会增加共享字符串表的总大小,并增加其在增长时调整大小的次数。更糟糕的是 - 在任何对子进程使用“写时复制”内存的环境(例如预分叉服务器)中,用于共享字符串表的内存页需要快速复制,因为子进程会操作哈希。因此,如果共享字符串表中的大部分键仅在一个地方使用,那么在 Perl 解释器中重复使用它们没有任何好处,但由于操作系统需要复制更多页面,因此成本很高。
现在可以配置 Perl 解释器以禁用“大型”哈希(既不是对象也不是符号表)的共享哈希键。为此,请将-Accflags='-DPERL_USE_UNSHARED_KEYS_IN_LARGE_HASHES'
添加到您的Configure选项中。“大型”是一个启发式方法 - 当前的启发式方法是,当向哈希添加键触发分配更多存储空间时,并且哈希具有超过 42 个键时,共享将被禁用。
这可能会导致创建包含多个共享相同键的大型哈希的(未祝福的)数据结构的程序的内存使用量略微增加。但总的来说,我们的测试表明,对于所描述的特定情况,这是一个胜利,其他代码不受影响。
在某些情况下,创建新的标量现在明显更快。
例如,以下代码现在执行速度提高了约 30%
$str = "A" x 64;
for (0..1_000_000) {
@svs = split //, $str
}
(您可以在 [perl #19414] 中阅读更多关于此内容的信息。)
Archive::Tar 已从版本 2.38 升级到 2.40。
Attribute::Handlers 已从版本 1.01 升级到 1.02。
attributes 已从版本 0.33 升级到 0.34。
B 已从版本 1.82 升级到 1.83。
B::Concise 已从版本 1.004 升级到 1.006。
B::Deparse 已从版本 1.56 升级到 1.64。
bignum 已从版本 0.51 升级到 0.65。
charnames 已从版本 1.48 升级到 1.50。
Compress::Raw::Bzip2 已从版本 2.101 升级到 2.103。
Compress::Raw::Zlib 已从版本 2.101 升级到 2.105。
CPAN 已从版本 2.28 升级到 2.33。
Data::Dumper 已从版本 2.179 升级到 2.184。
DB_File 已从版本 1.855 升级到 1.857。
Devel::Peek 已从版本 1.30 升级到 1.32。
Devel::PPPort 已从版本 3.62 升级到 3.68。
diagnostics 已从版本 1.37 升级到 1.39。
Digest 已从版本 1.19 升级到 1.20。
DynaLoader 已从版本 1.50 升级到 1.52。
Encode 已从版本 3.08 升级到 3.17。
Errno 已从版本 1.33 升级到 1.36。
experimental 已从版本 0.024 升级到 0.028。
Exporter 已从版本 5.76 升级到 5.77。
ExtUtils::MakeMaker 已从版本 7.62 升级到 7.64。
ExtUtils::Miniperl 已从版本 1.10 升级到 1.11。
ExtUtils::ParseXS 已从版本 3.43 升级到 3.45。
ExtUtils::Typemaps 已从版本 3.43 升级到 3.45。
Fcntl 已从版本 1.14 升级到 1.15。
feature 已从版本 1.64 升级到 1.72。
File::Compare 已从版本 1.1006 升级到 1.1007。
File::Copy 已从版本 2.35 升级到 2.39。
File::Fetch 已从版本 1.00 升级到 1.04。
File::Find 已从版本 1.39 升级到 1.40。
File::Glob 已从版本 1.33 升级到 1.37。
File::Spec 已从版本 3.80 升级到 3.84。
File::stat 已从版本 1.09 升级到 1.12。
FindBin 已从版本 1.52 升级到 1.53。
GDBM_File 已从版本 1.19 升级到 1.23。
Hash::Util 已从版本 0.25 升级到 0.28。
Hash::Util::FieldHash 已从版本 1.21 升级到 1.26。
HTTP::Tiny 已从版本 0.076 升级到 0.080。
I18N::Langinfo 已从版本 0.19 升级到 0.21。
if 已从版本 0.0609 升级到 0.0610。
IO 已从版本 1.46 升级到 1.50。
IO-Compress 已从版本 2.102 升级到 2.106。
IPC::Open3 已从版本 1.21 升级到 1.22。
JSON::PP 已从版本 4.06 升级到 4.07。
libnet 已从版本 3.13 升级到 3.14。
Locale::Maketext 已从版本 1.29 升级到 1.31。
Math::BigInt 已从版本 1.999818 升级到 1.999830。
Math::BigInt::FastCalc 已从版本 0.5009 升级到 0.5012。
Math::BigRat 已从版本 0.2614 升级到 0.2621。
Module::CoreList 已从版本 5.20210520 升级到 5.20220520。
mro 已从版本 1.25_001 升级到 1.26。
NEXT 已从版本 0.68 升级到 0.69。
Opcode 已从版本 1.50 升级到 1.57。
open 已从版本 1.12 升级到 1.13。
overload 已从版本 1.33 升级到 1.35。
perlfaq 已从版本 5.20210411 升级到 5.20210520。
PerlIO 已从版本 1.11 升级到 1.12。
Pod::Functions 已从版本 1.13 升级到 1.14。
Pod::Html 已从版本 1.27 升级到 1.33。
Pod::Simple 已从版本 3.42 升级到 3.43。
POSIX 已从版本 1.97 升级到 2.03。
re 已从版本 0.41 升级到 0.43。
Scalar::Util 已从版本 1.55 升级到 1.62。
sigtrap 已从版本 1.09 升级到 1.10。
Socket 已从版本 2.031 升级到 2.033。
sort 已从版本 2.04 升级到 2.05。
Storable 已从版本 3.23 升级到 3.26。
Sys::Hostname 已从版本 1.23 升级到 1.24。
Test::Harness 已从版本 3.43 升级到 3.44。
Test::Simple 已从版本 1.302183 升级到 1.302190。
Text::ParseWords 已从版本 3.30 升级到 3.31。
Text::Tabs 已从版本 2013.0523 升级到 2021.0814。
Text::Wrap 已从版本 2013.0523 升级到 2021.0814。
threads 已从版本 2.26 升级到 2.27。
threads::shared 已从版本 1.62 升级到 1.64。
Tie::Handle 已从版本 4.2 升级到 4.3。
Tie::Hash 已从版本 1.05 升级到 1.06。
Tie::Scalar 已从版本 1.05 升级到 1.06。
Tie::SubstrHash 已从版本 1.00 升级到 1.01。
Time::HiRes 已从版本 1.9767 升级到 1.9770。
Unicode::Collate 已从版本 1.29 升级到 1.31。
Unicode::Normalize 已从版本 1.28 升级到 1.31。
Unicode::UCD 已从版本 0.75 升级到 0.78。
UNIVERSAL 已从版本 1.13 升级到 1.14。
version 已从版本 0.9928 升级到 0.9929。
VMS::Filespec 已从版本 1.12 升级到 1.13。
VMS::Stdio 已从版本 2.45 升级到 2.46。
warnings 已从版本 1.51 升级到 1.58。
Win32 已从版本 0.57 升级到 0.59。
XS::APItest 已从版本 1.16 升级到 1.22。
XS::Typemap 已从版本 0.18 升级到 0.19。
XSLoader 已从版本 0.30 升级到 0.31。
本文档提供在 Perl 核心团队内管理选举或投票的流程。
我们已尝试更新文档以反映本文档中列出的更改。如果您发现我们遗漏了任何内容,请在 https://github.com/Perl/perl5/issues 上提交问题。
此外,还进行了以下选定更改
此文档已进行了一些清理,并且超过 80% 的(以前很多)未记录的函数现在要么已记录,要么被认为不适合标记为 API。
一如既往,欢迎补丁!
记录了从 Pod::Html 移动到 Pod::Html::Util 的函数的新位置,这些函数不再打算在核心之外使用。
记录了 :win32
IO 伪层已删除(此更改发生在 5.35.2 中)。
选举流程已进行微调,允许在候选人数量不超过空缺席位的情况下跳过投票。
现在允许将特别选举推迟最多 12 周,例如推迟到下次正常选举。
现在记录了调用者只需要是对象或类名才能进行方法调用,而不需要是子例程引用。
更新为不鼓励使用 /d 正则表达式修饰符。
-? 现在是 -h 的同义词
-g 现在是 -0777 的同义词
对诊断输出(包括警告和致命错误消息)进行了以下添加或更改。有关诊断消息的完整列表,请参阅 perldiag。
(F) 尝试使用控制流语句(如 return
、goto
或循环控制)跳出 defer 块的范围。这是不允许的。
无法在 %s 中修改 %s(用于将标量赋值为 undef
)
尝试将标量赋值为 undef
,例如通过 undef = $foo;
,以前会触发带有消息 "尝试修改只读值" 的致命运行时错误。在运行时之前检测到此类尝试赋值更有帮助,因此它们现在是编译时错误,导致消息 "无法在标量赋值中修改 undef 运算符"。
解析器在尝试解析 foreach
循环时,未能通过内部一致性检查。
正在调用 builtin::
命名空间中的函数,该函数目前处于实验阶段。
defer
块修饰符处于实验阶段。如果您想使用此功能,请使用 no warnings 'experimental::defer'
禁用警告,但请注意,这样做会冒您的代码在将来的 Perl 版本中可能出现问题的风险。
将 use VERSION 声明降级到低于 v5.11 已被弃用
此警告在 use VERSION
语句上发出,该语句请求低于 v5.11 的版本(此时 use strict
的效果将被禁用),在之前声明了具有更大数字的版本(这将启用这些效果)之后。
如果您使用 for
同时迭代多个值,则会发出此警告。此语法目前处于实验阶段,其行为可能会在将来的 Perl 版本中发生变化。
在使用签名的子例程中,发现了一个隐式包含 @_
参数数组的表达式。
在使用签名的子例程中,发现了一个包含 @_
参数数组的表达式。
尝试将宽字符放入程序名称 ($0
) 中现在会引发此警告。
此警告以前不包含 in %s
。
本地化子程序重新定义不再触发此警告。
unexpected constant lvalue entersub entry via type/targ %d:%d" 现在有一个 panic 前缀。
这使其与编译子程序时内部一致性的其他检查一致。
在标量上下文中无用地使用 sort 现在位于新的 scalar
类别中。
当 sort
在标量上下文中使用时,它会引发警告,表明这样做没有用。此警告以前位于 void
类别中。现在添加了一个用于警告标量上下文的新类别,称为 scalar
。
删除了一些诊断信息。
许多已从 perl 核心代码中删除多年的诊断信息现在也已从文档中删除。
Perl C 源代码现在使用了一些 C99 特性,我们已经验证了这些特性在我们目标的所有编译器中都受支持。这意味着 Perl 的头文件现在包含一些在 C99 中合法但在 C89 中不合法代码。
这可能会导致一些 XS 模块出现问题,这些模块在使用 gcc 或 clang 编译时,会无条件地将 -Werror=declaration-after-statement
添加到其 C 编译器标志中。早期的 Perl 版本支持长期过时的编译器,这些编译器在拒绝某些 C99 特性(特别是混合声明和代码)方面非常严格,因此 XS 模块作者审核其代码不违反此规则是有意义的。但是,现在只有在这些早期的 Perl 版本上才能做到这一点,因此这些模块需要更改为仅在 $] < 5.035005
时添加此标志。
makedepend 步骤现在使用 make 并行运行。
当使用 MAKEFLAGS=-j8 时,这会显著减少所需的时间。
sh ./makedepend MAKE=make cflags
Configure 现在测试是否需要 #include <xlocale.h>
来使用 POSIX 1003 线程安全区域设置函数或一些相关扩展。这可以防止在库更新中删除非公共 xlocale.h,或者 xlocale.h 不打算用于公共使用。(github #18936)
添加和更改了测试以反映此版本中的其他添加和更改。
已移除对旧版 MSVC++(VC12 之前版本)的支持
这些版本不支持 C99,因此不再可用于编译 Perl。
已添加对使用 Microsoft Visual Studio 2022(包含 Visual C++ 14.3)在 Windows 上编译 Perl 的支持。
已移除 :win32 IO 层。这个 :unix 层的实验性替代方案在近 20 年的发展中从未成熟。
keys %ENV
在 VMS 上返回一致的结果在 VMS 上,%ENV
哈希中的条目在第一次访问时从操作系统环境加载,因此 %ENV
的第一次迭代需要扫描整个环境以找到所有可能的键。此初始化始终对完整迭代正确执行,但以前对标量上下文中的 %ENV
没有执行,这意味着如果在任何其他 %ENV
访问之前调用 scalar %ENV
,它将返回 0,或者如果之前没有迭代,它将只返回已访问键的数量。
这些错误现在已修复 - 标量上下文中的 %ENV
和 keys %ENV
现在返回正确的结果 - 环境中所有键的数量。
UWIN 是 Windows 的 UNIX 兼容层。它最后一次发布是在 2012 年,现在已被 Cygwin 取代。
DJGPP 是 GNU 工具链移植到运行 DOS 的 32 位 x86 系统。最后一次已知的在它上面构建 Perl 的尝试是在 5.20,它只构建了 miniperl。
已移除对 Novell NetWare 的支持代码。NetWare 是 Novell 的服务器操作系统。该移植最后一次更新是在 2002 年 7 月,该平台本身是在 2009 年 5 月。
无关的更改在 2009 年 9 月意外破坏了 NetWare 移植的构建,并且在 12 年内没有人报告过此事。
此更新使我们能够构建 EBCDIC 静态/动态和 31 位/64 位寻址模式 Perl。通过的测试数量与这些更新之前的基线一致。
这些更改还提供了基础支持,以便能够提供 ASCII 静态/动态和 31 位/64 位寻址模式 Perl。
z/OS(以前称为 OS/390)自述文件已更新,以描述 ASCII 和 EBCDIC 构建。
自从 Perl 5.8 中删除 PERL_OBJECT 以来,PERL_IMPLICIT_CONTEXT 和 MULTIPLICITY 已成为同义词,并且它们被互换使用。为了简化代码,所有 PERL_IMPLICIT_CONTEXT 实例均已替换为 MULTIPLICITY。
PERL_IMPLICIT_CONTEXT 将继续定义以与 XS 模块兼容。
以前名为 G_ARRAY
的 API 常量(表示列表上下文)现已重命名为更准确的 G_LIST
。已添加兼容性宏 G_ARRAY
以允许现有代码不受影响地工作。新代码应使用新的常量而不是旧的常量。Devel::PPPort
版本 3.63 支持此功能。
已在 perl.h 中添加宏以方便版本比较:PERL_GCC_VERSION_GE
、PERL_GCC_VERSION_GT
、PERL_GCC_VERSION_LE
和 PERL_GCC_VERSION_LT
。
已在 embed.h 中添加内联函数以确定单词中最低有效位的位置:lsbit_pos32
和 lsbit_pos64
。
Perl_ptr_table_clear
已被删除。自 v5.14.0(于 2011 年发布)以来,此功能已被标记为已弃用,并且未被 CPAN 上的任何代码使用。
添加了新的布尔宏和函数。有关相关信息,请参见 "稳定布尔跟踪",有关文档,请参见 perlapi。
sv_setbool
sv_setbool_mg
SvIsBOOL
添加了 4 个用于处理 RV 的缺失函数
sv_setrv_noinc
sv_setrv_noinc_mg
sv_setrv_inc
sv_setrv_inc_mg
xs_handshake()
的两种失败模式现在提供不同的消息。
哈希迭代器状态(struct xpvhv_aux
)的内存现在作为哈希主体的一部分分配,而不是作为为主要哈希数组分配的内存块的一部分分配。
新的 phase_name() 接口提供了对每个解释器阶段(即 PL_phase 值)的名称的访问。
pack
对 U
的行为已针对 EBCDIC 进行了更改。
新增了等式测试函数 sv_numeq
和 sv_streq
,以及带有 ..._flags
后缀的变体。这些函数提供了一个简单一致的 API 用于执行数值或字符串比较,并且能够识别运算符重载。
读取整数值的字符串形式不再设置 SVf_POK
标志。字符串形式仍然在内部缓存,并且仍然通过宏 SvPV(sv)
等直接重新读取(内联,无需调用 C 函数)。已经调用 API 获取值的 XS 代码不会受到此更改的影响。直接访问标志而不是使用 API 调用来表达其意图的 XS 代码可能会出现问题,但如果传递其他值(例如浮点数或具有字符串重载的对象),此类代码可能已经存在错误。
这个小的改变允许代码(例如 JSON 序列化器)可靠地区分以下两种情况:
一个值最初以整数形式 **写入**,但随后以字符串形式 **读取**
my $answer = 42;
print "The answer is $answer\n";
同一个值最初以字符串形式 **写入**,但随后以整数形式 **读取**
my $answer = "42";
print "That doesn't look right\n"
unless $answer == 6 * 9;
对于第一种情况(最初以整数形式写入),我们现在有
use Devel::Peek;
my $answer = 42;
Dump ($answer);
my $void = "$answer";
print STDERR "\n";
Dump($answer)
SV = IV(0x562538925778) at 0x562538925788
REFCNT = 1
FLAGS = (IOK,pIOK)
IV = 42
SV = PVIV(0x5625389263c0) at 0x562538925788
REFCNT = 1
FLAGS = (IOK,pIOK,pPOK)
IV = 42
PV = 0x562538919b50 "42"\0
CUR = 2
LEN = 10
对于第二种情况(最初以字符串形式写入),我们现在有
use Devel::Peek;
my $answer = "42";
Dump ($answer);
my $void = $answer == 6 * 9;
print STDERR "\n";
Dump($answer)'
SV = PV(0x5586ffe9bfb0) at 0x5586ffec0788
REFCNT = 1
FLAGS = (POK,IsCOW,pPOK)
PV = 0x5586ffee7fd0 "42"\0
CUR = 2
LEN = 10
COW_REFCNT = 1
SV = PVIV(0x5586ffec13c0) at 0x5586ffec0788
REFCNT = 1
FLAGS = (IOK,POK,IsCOW,pIOK,pPOK)
IV = 42
PV = 0x5586ffee7fd0 "42"\0
CUR = 2
LEN = 10
COW_REFCNT = 1
(不能依赖 SVf_IsCOW
标志的存在或不存在来确定标量操作的历史。)
以前这两种情况是无法区分的,所有 4 个标志都被设置
SV = PVIV(0x55d4d62edaf0) at 0x55d4d62f0930
REFCNT = 1
FLAGS = (IOK,POK,pIOK,pPOK)
IV = 42
PV = 0x55d4d62e1740 "42"\0
CUR = 2
LEN = 10
(并且可能设置了 SVf_IsCOW
,但并非总是如此)
现在,这意味着如果 XS 代码确实需要确定值的最初写入形式,它应该实现类似的逻辑
if (flags & SVf_IOK|SVf_NOK) && !(flags & SVf_POK)
serialize as number
else if (flags & SVf_POK)
serialize as string
else
the existing guesswork ...
请注意,这并不涵盖“双变量”——当要求其字符串形式或数字形式时报告不同值的标量(例如 $!
)。大多数序列化格式无法表示这种重复性。
现有的猜测仍然存在,因为除了双变量之外,值可能为 undef
、引用、重载引用、类型全局变量和其他 Perl 本身可以表示但不能一对一映射到外部格式的事物,因此需要一定程度的近似或封装。
sv_dump
(以及 Devel::Peek 的 Dump
函数)现在将 PV 中的高位字节以十六进制而不是八进制形式转义。由于大多数人更容易理解十六进制而不是八进制,因此这应该使这些转储更易读。这 **不会** 影响任何其他诊断接口,例如 pv_display
。
utime() 现在在对已关闭的句柄调用时会正确设置 errno/$!
。
在调用 magic 之前,以前会检查 setsockopt() 的 OPTVAL 参数上的标志,可能将数值视为打包缓冲区或反之亦然。它还忽略了 UTF-8 标志,可能将升级的 SV 的内部表示视为提供给 setsockopt() 系统调用的字节。(github #18660)
仅设置 IOKp,而不是 IOK 在 $) 和 $( 上。这是问题 #18955:这将阻止序列化器将这些变量序列化为数字(这会丢失额外的组)。这恢复了 5.16 的行为。
使用 mktables
调试工具会导致 perl 从 v5.31.10 开始崩溃;此问题现已修复。
makedepend
逻辑现在与 BSD make 兼容(修复了 GH #19046)。
在正在迭代的绑定哈希上调用 untie
现在会立即释放迭代状态。
迭代绑定哈希会导致 perl 存储当前哈希键的副本以跟踪迭代状态,并将此存储的副本作为第二个参数传递给 NEXTKEY
。此内部状态在绑定哈希迭代完成后或哈希被销毁时会立即释放,但由于实现疏忽,如果哈希被解绑,它不会被释放。在这种情况下,键的内部副本将一直保留到以下情况中的最早情况:
tie
再次在同一个哈希上调用
哈希被迭代(即传递给任何 keys
、values
或 each
)
哈希被销毁。
此不一致性现已修复 - 内部状态现在由 untie
立即释放。
由于此行为的确切时间可以观察到纯 Perl 代码(从 FIRSTKEY
和 NEXTKEY
返回的对象上的 DESTROY
的时间),因此某些代码可能对此敏感。
为在 perl 5.30.0 中引导 miniperl 而添加的 Internals::getcwd()
函数现在仅在 miniperl 中可用。[github #19122]
在 BEGIN 或等效的 use
语句上设置断点可能会导致内存写入已释放的 dbstate
操作。[GH #19198]
当禁用裸字文件句柄时,解析器会将任何裸字解释为文件句柄,即使紧随其后的是括号。
perl5300delta 错误地识别了一个 CVE,其正确标识为 CVE-2015-1592。
Raun "Spider" Boardman(CPAN 上的 SPIDB),在 1996 年至 2002 年间至少为 Perl 5 核心发行版贡献了 66 次提交,于 2021 年 5 月 24 日因 COVID 相关并发症去世。我们将怀念他。
David H. Adler (DHA) 于 2021 年 11 月 16 日去世。1997 年,David 共同创立了第一个 Perl 用户组 NY.pm,1998 年共同创立了 Perl Mongers,以帮助在全球范围内建立其他用户组。他经常参加北美和欧洲的 Perl 大会,并以在这些大会上组织烂片之夜庆祝活动而闻名。他还为 Perl 基金会的工作做出了贡献,包括管理社区服务的白骆驼奖。我们将怀念他。
Perl 5.36.0 代表了自 Perl 5.34.0 以来大约一年的开发,包含来自 82 位作者的 2,000 个文件中的大约 250,000 行更改。
不包括自动生成的 文件、文档和发布工具,对 1,300 个 .pm、.t、.c 和 .h 文件进行了大约 190,000 行更改。
得益于充满活力的用户和开发人员社区,Perl 继续在它的第四个十年蓬勃发展。以下人员已知为 Perl 5.36.0 的改进做出了贡献。
Alyssa Ross,Andrew Fresh,Aristotle Pagaltzis,Asher Mancinelli,Atsushi Sugawara,Ben Cornett,Bernd,Biswapriyo Nath,Brad Barden,Bram,Branislav Zahradník,brian d foy,Chad Granum,Chris 'BinGOs' Williams,Christian Walde (Mithaldu),Christopher Yeleighton,Craig A. Berry,cuishuang,Curtis Poe,Dagfinn Ilmari Mannsåker,Dan Book,Daniel Laügt,Dan Jacobson,Dan Kogai,Dave Cross,Dave Lambley,David Cantrell,David Golden,David Marshall,David Mitchell,E. Choroba,Eugen Konkov,Felipe Gasper,François Perrad,Graham Knop,H.Merijn Brand,Hugo van der Sanden,Ilya Sashcheka,Ivan Panchenko,Jakub Wilk,James E Keenan,James Raspass,Karen Etheridge,Karl Williamson,Leam Hall,Leon Timmermans,Magnus Woldrich,Matthew Horsfall,Max Maischein,Michael G Schwern,Michiel Beijen,Mike Fulton,Neil Bowers,Nicholas Clark,Nicolas R,Niyas Sait,Olaf Alders,Paul Evans,Paul Marquess,Petar-Kaleychev,Pete Houston,Renee Baecker,Ricardo Signes,Richard Leach,Robert Rothenberg,Sawyer X,Scott Baker,Sergey Poznyakoff,Sergey Zhmylove,Sisyphus,Slaven Rezic,Steve Hay,Sven Kirmess,TAKAI Kousuke,Thibault Duponchelle,Todd Rinaldo,Tomasz Konojacki,Tomoyuki Sadahiro,Tony Cook,Unicode Consortium,Yves Orton,Михаил Козачков。
上面的列表几乎肯定是不完整的,因为它是由版本控制历史自动生成的。特别是,它不包括向 Perl 错误跟踪器报告问题的贡献者(非常感谢)的姓名。
此版本中包含的许多更改源自 Perl 核心包含的 CPAN 模块。我们感谢整个 CPAN 社区帮助 Perl 蓬勃发展。
有关 Perl 所有历史贡献者的更完整列表,请参阅 Perl 源代码分发中的 AUTHORS 文件。
如果您发现您认为是错误的内容,您可以在 https://github.com/Perl/perl5/issues 上查看 perl 错误数据库。您也可以在 https://www.perl5.cn/(Perl 主页)上找到信息。
如果您认为您遇到了未报告的错误,请在 https://github.com/Perl/perl5/issues 上创建一个问题。请务必将您的错误缩减为一个微小但足够的测试用例。
如果您报告的错误存在安全隐患,不适合发送到公共问题跟踪器,请参阅 "perlsec 中的 SECURITY VULNERABILITY CONTACT INFORMATION",了解如何报告该问题。
如果您想感谢 Perl 5 维护人员在 Perl 5 中所做的工作,您可以运行 perlthanks
程序。
perlthanks
这将向 Perl 5 Porters 列表发送一封电子邮件,以表达您的感谢。
有关更改的详细说明,请参阅 Changes 文件。
有关如何构建 Perl 的说明,请参阅 INSTALL 文件。
有关一般信息,请参阅 README 文件。
有关版权信息,请参阅 Artistic 和 Copying 文件。