内容

名称

perl5260delta - perl v5.26.0 的新增功能

描述

本文档描述了 5.24.0 版本和 5.26.0 版本之间的差异。

注意

此版本包含三个具有广泛影响的更新

核心增强

词法子程序不再是实验性的

使用 v5.18 中引入的 lexical_subs 特性不再发出警告。以前使用该特性禁用 experimental::lexical_subs 警告类别的现有代码将继续工作。lexical_subs 特性没有影响;所有 Perl 代码都可以使用词法子程序,无论作用域中有哪些特性声明。

缩进的 Here-文档

这为 Here-文档添加了一个新的修饰符 "~",它告诉解析器应该查找 /^\s*$DELIM\n/ 作为结束分隔符。

所有这些语法都受支持

<<~EOF;
<<~\EOF;
<<~'EOF';
<<~"EOF";
<<~`EOF`;
<<~ 'EOF';
<<~ "EOF";
<<~ `EOF`;

"~" 修饰符将从 Here-文档中的每一行中剥离与分隔符之前出现的相同空白。

换行符将按原样复制,而没有包含正确开头空白的行将导致 perl 抛出异常。

例如

if (1) {
  print <<~EOF;
    Hello there
    EOF
}

打印 "Hello there\n",没有前导空白。

新的正则表达式修饰符 /xx

指定两个 "x" 字符来修改正则表达式模式会执行单个 "x" 字符所做的一切,但此外,方括号字符类中的 TAB 和 SPACE 字符通常会被忽略,并且可以添加以提高可读性,例如 /[ ^ A-Z d-f p-x ]/xx。详细信息请参见 perlre 中的 "/x 和 /xx".

@{^CAPTURE}%{^CAPTURE}%{^CAPTURE_ALL}

@{^CAPTURE} 将最后一次匹配的捕获缓冲区公开为数组。因此 $1 等于 ${^CAPTURE}[0]。这与类似 substr($matched_string,$-[0],$+[0]-$-[0]) 的代码等效,并且您也不必跟踪 $matched_string。此变量没有单字符等效项。请注意,与其他正则表达式魔术变量一样,此变量的内容是动态的;如果您希望在匹配生命周期之外存储它,则必须将其复制到另一个数组中。

%{^CAPTURE} 等效于 %+(即命名捕获)。除了更具自述性之外,两种形式之间没有区别。

%{^CAPTURE_ALL} 等同于 %-(即所有命名的捕获)。除了更具自述性之外,两种形式之间没有区别。

声明对变量的引用

作为一项实验性功能,Perl 现在允许引用运算符出现在 my()state()our()local() 之后。此语法必须使用 use feature 'declared_refs' 启用。它处于实验阶段,默认情况下会发出警告,除非 no warnings 'experimental::refaliasing' 生效。它主要用于对引用的赋值。例如

use experimental 'refaliasing', 'declared_refs';
my \$a = \$b;

有关更多详细信息,请参见 "perlref 中的“对引用的赋值”"

现在支持 Unicode 9.0

更改列表位于 http://www.unicode.org/versions/Unicode9.0.0/。与核心 Perl 一起发布但未由 p5p 维护的模块不一定支持 Unicode 9.0。 Unicode::Normalize 确实适用于 9.0。

\p{script} 的使用使用了改进的 Script_Extensions 属性

Unicode 6.0 引入了改进的 Script (sc) 属性形式,并将其称为 Script_Extensions (scx)。当属性仅指定为 \p{script} 时,Perl 现在使用此改进版本。这应该使程序在确定字符是否在给定脚本中使用时更加准确,但对于非常具体地需要旧行为的程序,可能会出现轻微的破坏。复合形式的含义,如 \p{sc=script} 保持不变。请参见 "perlunicode 中的“脚本”"

Perl 现在可以在支持它的平台上的 UTF-8 本地化中进行默认排序

一些平台在 UTF-8 本地化中本机地对排序和排序进行了合理的处理。Perl 现在可以与它们一起使用。为了便携性和完全控制,仍然建议使用 Unicode::Collate,但现在您可能不需要做任何特殊的事情来获得足够好的结果,具体取决于您的应用程序。请参见 "perllocale 中的“类别 LC_COLLATE:排序:文本比较和排序”"

包含嵌入式 NUL 字符的字符串的更好的本地化排序

在具有多级字符权重的区域设置中,NUL现在在较高优先级中被忽略。不过,在某些字符串中仍然存在一些问题。请参阅 "perllocale 中包含嵌入式 NUL 字符的字符串的排序"

CORE 子例程,用于通过引用调用的哈希和数组函数

CORE 命名空间中的哈希和数组函数(keyseachvaluespushpopshiftunshiftsplice)现在可以使用取地址符语法(&CORE::keys(\%hash)和通过引用(my $k = \&CORE::keys; $k->(\%hash))调用。以前,它们只能在内联时使用。

用于 64 位构建的新哈希函数

我们已切换到混合哈希函数,以更好地平衡短键和长键的性能。

对于短键(16 字节及以下),我们使用 One At A Time Hard 的优化变体,而对于长键,我们使用 Siphash 1-3。对于非常长的键,这在性能方面是一个很大的改进。对于较短的键,性能有所提高。

安全

@INC 中删除当前目录("."

perl 二进制文件在 @INC 中包含一组默认路径。历史上,它还包含当前目录(".")作为最后一个条目,除非在启用 taint 模式(perl -T)的情况下运行。虽然很方便,但这存在安全隐患:例如,当脚本尝试加载可选模块时,其当前目录不可信(例如 /tmp),它可能会从该目录下加载并执行代码。

从 v5.26 开始,"." 默认情况下始终被删除,而不仅仅是在 taint 模式下。这对安装模块和执行脚本有重大影响。

以下新功能已添加,以帮助缓解这些问题。

以下是脚本和模块作者可能需要做的一些事情,以使他们的软件在新环境中正常工作。

PATH 中转义的冒号和相对路径

在 Unix 系统上,Perl 在启动新进程时会将 PATH 环境变量中的任何相对路径视为受污染的。以前,它允许使用反斜杠来转义冒号(与操作系统不同),因此如果将 PATH 设置为类似 /\:. 的内容,则相对路径会被认为是安全的。该检查已修复,在该示例中将 "." 视为受污染的。

现在需要新的 -Di 开关才能输出 PerlIO 调试信息

这用于调试 PerlIO 中的代码,以避免递归调用。以前,如果 perl 不是以 setuid 方式运行,并且尚未解析 -T-t 开关,则此输出将发送到 PERLIO_DEBUG 环境变量指定的 文件。

如果 perl 在尚未解析其开关的情况下执行输出,这可能会导致 perl 创建或覆盖 PERLIO_DEBUG 指定的文件,即使提供了 -T 开关也是如此。

Perl 现在要求在生成 PerlIO 调试输出之前存在 -Di 开关。默认情况下,它会写入 stderr,但可以选择通过设置 PERLIO_DEBUG 环境变量将其重定向到文件。

如果 perl 以 setuid 方式运行或提供了 -T 开关,则会忽略 PERLIO_DEBUG,并且调试输出将发送到 stderr,就像任何其他 -D 开关一样。

不兼容的更改

正则表达式模式中未转义的字面量 "{" 字符不再允许

您现在必须使用类似 "\{""[{]" 的内容来指定匹配左大括号;否则,它将是一个致命的模式编译错误。此更改将允许将来对语言进行扩展。

这些自 v5.16 起已弃用,从 v5.22 开始,某些使用情况会引发弃用消息。不幸的是,添加用于引发消息的代码存在错误,并且在某些情况下未能发出警告,而这些情况下本应发出警告。因此,对这些情况的禁令执行推迟到 Perl 5.30,但代码已修复,以便在此期间为它们引发默认开启的弃用消息。

字面量 "{" 的某些使用情况发生在我们预计其含义永远不会是字面量以外的任何内容的上下文中,例如模式中的第一个字符,或在 "|" 后面表示交替。因此

qr/{fee|{fie/

匹配字符串 {fee{fie 中的任意一个。为了避免强制进行不必要的代码更改,这些使用不需要转义,也不会发出警告,目前也没有计划更改这一点。

但始终正确地转义 "{",记住的简单规则是始终这样做。

参见 正则表达式中未转义的左大括号在此处是非法的

scalar(%hash) 返回签名已更改

scalar(%hash) 返回的值将不再显示有关哈希中分配的桶的信息。它将简单地返回已使用键的计数。因此,它等效于 0+keys(%hash)

通过 Hash::Util::bucket_ratio() 提供了一种向后兼容的形式,它提供了与 Perl 5.24 及更早版本中提供的 scalar(%hash) 相同的行为。

keys 从左值子例程返回

从左值子例程返回的 keys 不能再在列表上下文中赋值。

sub foo : lvalue { keys(%INC) }
(foo) = 3; # death
sub bar : lvalue { keys(@_) }
(bar) = 3; # also an error

这使得左值子例程情况与 (keys %hash) = ...(keys @_) = ... 一致,它们也是错误的。 [GH #15339]

${^ENCODING} 功能已移除

与为该变量赋值相关的特殊行为已被移除。因此,encoding 编译指示的默认模式不再受支持。如果您仍然需要以 UTF-8 以外的编码编写源代码,请使用源代码过滤器,例如 CPAN 上的 Filter::EncodingencodingFilter 选项。

POSIX::tmpnam() 已移除

在 Perl 5.22 中,基本不安全的 tmpnam() 接口已弃用,现在已移除。作为替代,您可以使用例如 File::Temp 接口。

require ::Foo::Bar 现在是非法的。

以前,require ::Foo::Bar 会尝试读取 /Foo/Bar.pm。现在,任何以双冒号开头的裸字 require 都会导致死亡。

字面控制字符变量名不再允许

变量名不再允许包含字面控制字符。这些以前在 ASCII 平台上的单字符名称中是允许的,但从 Perl 5.20 开始就被弃用。这会影响诸如 $\cT 之类的东西,其中 \cT 是源代码中的字面控制字符(例如 NAKNEGATIVE ACKNOWLEDGE 字符)。

NBSP\N{...} 中不再允许

字符名称不再允许包含不间断空格。从 Perl 5.22 开始,这种做法已被弃用。

弃用功能

不再允许使用非独立字素作为字符串分隔符

为了让 Perl 最终能够允许使用 Unicode 字素簇作为字符串分隔符(看起来像单个字符,但实际上可能是多个字符的序列),我们必须停止允许使用非独立字素作为单个字符分隔符。这些分隔符在实际代码中不太可能存在,因为它们通常会显示为附加到前面的字符。

\cX 映射到可打印字符不再被弃用

这意味着我们没有计划删除此功能。它仍然会发出警告,但只有在启用语法警告时才会发出。此功能最初旨在提供一种表达没有助记符的不可打印字符的方法(\t\n 是两个不可打印字符的助记符,但大多数不可打印字符没有助记符)。但是,此功能可以用来指定一些可打印字符,尽管这些字符更清楚地表达为可打印字符本身。请参阅 http://www.nntp.perl.org/group/perl.perl5.porters/2017/02/msg242944.html

性能增强

模块和语义

更新的模块和语义

文档

新文档

perldeprecation

此文件记录了所有即将弃用的功能,以及一些已经移除的弃用功能。此文档的目的是双重的:记录哪些功能将消失以及将在哪个版本消失,并为处理代码的人提供指南,这些代码在升级 Perl 后不再具有某些功能。

现有文档的更改

我们已尝试更新文档以反映此文档中列出的更改。如果您发现任何遗漏的更改,请发送电子邮件至 [email protected]

此外,所有对 Usenet 的引用都已删除,并进行了以下选定更改

perlfunc

perlguts

perlhack

perlhacktips

perlinterp

perllocale

perlmod

perlmodlib

perlobj

perlootut

perlop

perlre

perlretut

perlunicode

perlvar

诊断信息

新的诊断信息

新的错误

新的警告

对现有诊断的更改

实用程序更改

c2phpstruct

Porting/pod_lib.pl

Porting/sync-with-cpan

perf/benchmarks

Porting/checkAUTHORS.pl

t/porting/regen.t

utils/h2xs.PL

perlbug

配置和编译

测试

测试被添加和更改以反映此版本中的其他添加和更改。此外,还进行了以下实质性更改

平台支持

新平台

NetBSD/VAX

Perl 现在可以在 VAX 机器上的 NetBSD 上编译。但是,该平台无法实现与大多数现代系统兼容的浮点无穷大和 NaN,这些系统实现了 IEEE-754 浮点标准。十六进制浮点数(0x...p[+-]n 字面量,printf %a)也没有实现。make test 通过了 98% 的测试。

  • 测试修复和次要更新。

  • 考虑缺乏 infnan-0.0 支持。

平台特定说明

Darwin
  • 不要将 -Dprefix=/usr 视为特殊情况:而是需要额外的选项 -Ddarwin_distribution 才能产生相同的结果。

  • OS X El Capitan 未实现 clock_gettime()clock_getres() API;根据需要模拟它们。

  • macOS 10.12 上已弃用 syscall(2)

EBCDIC

一些测试已更新以在 EBCDIC 平台上工作(或被跳过)。

HP-UX

Net::Ping UDP 测试现在在 HP-UX 上被跳过。

Hurd

Hurd 的提示已得到改进,支持 malloc 包装并报告使用的 GNU libc(以前报告为空字符串)。

VAX

NetBSD 现在支持 VAX 浮点格式。

VMS
  • 在 Unix shell 下运行时,PERL5LIBPERLLIB 环境条目中的路径分隔符现在为冒号 (":")。在 DCL 下运行时没有变化(仍然是 "|")。

  • configure.com 现在识别 VSI 品牌的 C 编译器,不再识别“DEC”品牌的 C 编译器(因为 15 年或更长时间以来就没有这样的编译器了)。

Windows
  • 添加了使用 Microsoft Visual Studio 2015(包含 Visual C++ 14.0)在 Windows 上编译 perl 的支持。

    此版本的 VC++ 包含一个完全重写的 C 运行时库,其中的一些更改意味着在 perl #120091 和 perl #118059 中解决套接字 close() 错误所做的工作,在当前状态下无法与此版本的 VC++ 一起使用。因此,我们实际上已针对 VS2015 及更高版本恢复了该错误修复,因为能够使用 VS2015 及更高版本比保留错误修复更重要。我们可能会在将来重新审视这个问题,尝试以与 VS2015 兼容的方式再次修复该错误。

    这些更改不会影响使用 GCC 或 Visual Studio 版本(包括 VS2013)进行编译,即,对于这些编译器,错误修复将保留(不变)。

    请注意,如果您将使用 GCC 或 VS <= VS2013 构建的 perl 与使用 VS2015 构建的 XS 模块混合使用,或者如果您将使用 VS2015 构建的 perl 与使用 GCC 或 VS <= VS2013 构建的 XS 模块混合使用,您可能会遇到兼容性问题。一些不兼容性可能是由于针对 VS2015 构建的 perl 恢复的错误修复造成的,但由于 VS2015 中的重写 CRT,也可能存在不兼容性(例如,请参阅 http://stackoverflow.com/questions/30412951 中的讨论)。

  • 它现在会自动检测 GCC 与 Visual C,并在 Win32 上设置 VC 版本号。

Linux

放弃对 Linux a.out 可执行文件格式的支持。Linux 已使用 ELF 超过 20 年。

OpenBSD 6

OpenBSD 6 仍然不支持使用 SA_SIGINFO 返回 pidgiduid。请确保对此进行处理。

FreeBSD

t/uni/overload.t:跳过 FreeBSD 上挂起的测试。

DragonFly BSD

DragonFly BSD 现在支持 setproctitle()[GH #15703].

内部更改

选定的错误修复

已知问题

先前版本中的勘误

讣告

Jon Portnoy (AVENJ),一位多产的 Perl 作者和备受尊敬的 Gentoo 社区成员,于 2016 年 8 月 10 日去世。所有与他接触过的人都会怀念他,他的智慧、机智和精神会永远留存。

我们也怀着沉痛的心情,哀悼 Kip Hampton 的逝世。他最广为人知的是 XML.com 上 Perl & XML 专栏的作者,他是 AxKit 的核心贡献者,AxKit 是一个 XML 服务器平台,后来成为 Apache 基金会的项目。在 OSCON 的早期,他经常发言,最近一次是在麦迪逊的 YAPC::NA 上。他经常在 irc.perl.org 上以 ubu 的身份出现,通常在 #axkit-dahut 社区,该社区负责 2011 年在阿什维尔的 YAPC::NA。

Kip 和他对社区的持续贡献将被深深地怀念。

致谢

Perl 5.26.0 代表了自 Perl 5.24.0 发布以来的大约 13 个月的开发,包含了来自 86 位作者的 2,600 个文件中的大约 360,000 行代码变更。

不包括自动生成的代码、文档和发布工具,对 1,800 个 .pm、.t、.c 和 .h 文件进行了大约 230,000 行代码变更。

Perl 进入第三个十年,依然蓬勃发展,这得益于充满活力的用户和开发者社区。以下人员为 Perl 5.26.0 的改进做出了贡献。

Aaron Crane, Abigail, Ævar Arnfjörð Bjarmason, Alex Vandiver, Andreas König, Andreas Voegele, Andrew Fresh, Andy Lester, Aristotle Pagaltzis, Chad Granum, Chase Whitener, Chris 'BinGOs' Williams, Chris Lamb, Christian Hansen, Christian Millour, Colin Newell, Craig A. Berry, Dagfinn Ilmari Mannsåker, Dan Collins, Daniel Dragan, Dave Cross, Dave Rolsky, David Golden, David H. Gutteridge, David Mitchell, Dominic Hargreaves, Doug Bell, E. Choroba, Ed Avis, Father Chrysostomos, François Perrad, Hauke D, H.Merijn Brand, Hugo van der Sanden, Ivan Pozdeev, James E Keenan, James Raspass, Jarkko Hietaniemi, Jerry D. Hedden, Jim Cromie, J. Nick Koston, John Lightsey, Karen Etheridge, Karl Williamson, Leon Timmermans, Lukas Mai, Matthew Horsfall, Maxwell Carey, Misty De Meo, Neil Bowers, Nicholas Clark, Nicolas R., Niko Tyni, Pali, Paul Marquess, Peter Avalos, Petr Písař, Pino Toscano, Rafael Garcia-Suarez, Reini Urban, Renee Baecker, Ricardo Signes, Richard Levitte, Rick Delaney, Salvador Fandiño, Samuel Thibault, Sawyer X, Sébastien Aperghis-Tramoni, Sergey Aleynikov, Shlomi Fish, Smylers, Stefan Seifert, Steffen Müller, Stevan Little, Steve Hay, Steven Humphrey, Sullivan Beck, Theo Buehler, Thomas Sibley, Todd Rinaldo, Tomasz Konojacki, Tony Cook, Unicode Consortium, Yaroslav Kuzmin, Yves Orton, Zefram.

上面的列表几乎肯定是不完整的,因为它是由版本控制历史自动生成的。特别是,它不包括向 Perl 错误跟踪器报告问题的贡献者(非常感谢)的姓名。

此版本中包含的许多更改源自 Perl 内核中包含的 CPAN 模块。我们感谢整个 CPAN 社区帮助 Perl 蓬勃发展。

有关 Perl 所有历史贡献者的更完整列表,请参阅 Perl 源代码分发中的 AUTHORS 文件。

报告错误

如果您发现您认为是错误的内容,您可以在 https://rt.perl.org/ 上查看 perl 错误数据库。您也可以在 https://www.perl5.cn/(Perl 主页)上找到信息。

如果您认为您遇到了未报告的错误,请运行随您的版本一起提供的 perlbug 程序。请务必将您的错误缩减为一个微小但足够的测试用例。您的错误报告以及 perl -V 的输出将被发送到 [email protected],由 Perl 移植团队进行分析。

如果您报告的错误存在安全隐患,不适合发送到公开存档的邮件列表,请参阅 "perlsec 中的 SECURITY VULNERABILITY CONTACT INFORMATION",了解如何报告该问题。

致谢

如果您想感谢 Perl 5 移植者在 Perl 5 中所做的工作,您可以运行 perlthanks 程序。

perlthanks

这将向 Perl 5 Porters 列表发送一封电子邮件,以表达您的感谢。

另请参阅

有关更改内容的详细说明,请参阅Changes文件。

有关如何构建 Perl 的说明,请参阅INSTALL文件。

有关一般信息,请参阅README文件。

有关版权信息,请参阅ArtisticCopying文件。