内容

名称

perl56delta - perl v5.6.0 的新增功能

说明

本文档介绍了 5.005 版本和 5.6.0 版本之间的差异。

核心增强功能

解释器克隆、线程和并发

Perl 5.6.0 引入了在不同线程中同时运行多个解释器的支持的开端。结合 perl_clone() API 调用(可用于选择性地复制任何给定解释器的状态),可以一次在一个解释器中编译一段代码,克隆该解释器一次或多次,并在不同的线程中运行所有生成的解释器。

在 Windows 平台上,此功能用于在解释器级别模拟 fork()。有关此功能的详细信息,请参阅 perlfork

此功能仍在发展中。最终,它将用于选择性地克隆子例程和可从该子例程访问的数据,并将其克隆到一个单独的解释器中,并在一个单独的线程中运行克隆的子例程。由于解释器之间没有共享数据,因此几乎不需要锁定(除非符号表的部分显式共享)。显然,这是对现有线程支持的一种易于使用的替代方案。

可以使用 -Dusethreads Configure 选项启用克隆解释器和解释器并发的支持(有关如何在 Windows 上启用它,请参阅 win32/Makefile。)生成的 perl 可执行文件在功能上与使用 -Dmultiplicity 构建的可执行文件相同,但 perl_clone() API 调用仅在前者中可用。

-Dusethreads 默认启用 cpp 宏 USE_ITHREADS,进而启用 Perl 源代码更改,以便在 op 树和它操作的数据之间提供明确的分离。前者是不可变的,因此可以在解释器及其所有克隆之间共享,而后者被认为是每个解释器的局部变量,因此为每个克隆复制。

请注意,如果你希望在不同的线程中同时运行多个独立解释器,则使用 -Dusemultiplicity Configure 选项构建 Perl 就足够了。-Dusethreads 仅提供 perl_clone() API 调用和其他支持以同时运行克隆解释器的附加功能。

NOTE: This is an experimental feature.  Implementation details are
subject to change.

词法作用域警告类别

你现在可以使用 use warnings pragma 更精细地控制 perl 发出的警告粒度。warningsperllexwarn 对此功能有大量的文档。

Unicode 和 UTF-8 支持

Perl 现在使用 UTF-8 作为其字符字符串的内部表示。utf8bytes pragma 用于控制当前词法作用域中的此支持。有关更多信息,请参阅 perlunicodeutf8bytes

此功能预计将快速发展,以支持某种形式的 I/O 规则,该规则可用于指定输入和输出数据(字节或字符)的类型。在实现之前,需要来自 CPAN 的其他模块来完成处理 Unicode 的工具包。

NOTE: This should be considered an experimental feature.  Implementation
details are subject to change.

支持内插命名字符

新的 \N 转义符在字符串中内插命名字符。例如,"Hi! \N{WHITE SMILING FACE}" 计算结果为一个字符串,末尾带有 unicode 笑脸。

"our" 声明

"our" 声明引入了一个值,可以最好地理解为在变量声明所在包中的全局变量的词法作用域符号别名。这主要用作 vars pragma 的替代方案,但也提供了为这些变量引入类型和其他属性的机会。请参阅 "our" in perlfunc

支持表示为序数向量的字符串

现在,v1.2.3.4 形式的字面量被解析为由具有指定序数的字符组成的字符串。这是一种替代的、更易读的方式来构造(可能是 unicode)字符串,而不是像 "\x{1}\x{2}\x{3}\x{4}" 那样插入字符。如果序数多于两个,则可以省略前导的 v,因此 1.2.3 的解析方式与 v1.2.3 相同。

以这种形式编写的字符串对于表示版本“数字”也很有用。使用任何通常的字符串比较运算符 eqneltgt 等,很容易比较此类版本“数字”(实际上只是普通字符串),或使用 |& 等对它们执行按位字符串运算。

结合新的 $^V 魔术变量(包含 perl 版本作为字符串),此类字面量可以用作一种可读的方式来检查你是否运行的是特定版本的 Perl

# this will parse in older versions of Perl also
if ($^V and $^V gt v5.6.0) {
    # new features supported
}

requireuse 还有一些特殊魔术来支持此类字面量,但应避免这种特定用法,因为它会导致在不支持向量字符串的 Perl 版本下产生误导性错误消息。使用真正的版本号将确保在所有版本的 Perl 中行为正确

require 5.006;    # run time check for v5.6
use 5.006_001;    # compile time check for v5.6.1

此外,sprintfprintf 支持 Perl 特定的格式标志 %v,以打印任意字符串中字符的序数

printf "v%vd", $^V;		# prints current version, such as "v5.5.650"
printf "%*vX", ":", $addr;	# formats IPv6 address
printf "%*vb", " ", $bits;	# displays bitstring

有关其他信息,请参阅 perldata 中的 "标量值构造函数"

改进的 Perl 版本编号系统

从 Perl 版本 5.6.0 开始,版本编号约定已更改为“点分整数”方案,这在开源项目中更常见。

v5.6.0 的维护版本将发布为 v5.6.1、v5.6.2 等。v5.6.0 之后的下一个开发系列将编号为 v5.7.x,从 v5.7.0 开始,v5.6.0 之后的下一个主要生产版本将为 v5.8.0。

English 模块现在将 $PERL_VERSION 设置为 $^V(一个字符串值),而不是 $](一个数字值)。(这是一个潜在的不兼容性。如果你受到此影响,请通过 perlbug 向我们发送报告。)

v1.2.3 语法现在在 Perl 中也是合法的。有关更多信息,请参阅 "支持表示为序数向量的字符串"

为了应对新版本控制系统对每个版本组件使用至少三位有效数字,用于递增版本号的方法也略有改变。我们假设 v5.6.0 之前的版本以 10 的倍数递增版本组件。v5.6.0 之后的版本将以 1 递增它们。因此,使用新符号,5.005_03 “相同于” v5.5.30,并且 v5.6.0 之后的第一个维护版本将是 v5.6.1(应该理解为等效于旧格式中存储在 $] 中的浮点值 5.006_001)。

声明子例程属性的新语法

以前,如果你想将子例程标记为方法调用或在进入时需要自动 lock(),则必须在子例程的主体中使用 use attrs pragma 声明。现在可以使用声明语法来完成,如下所示

    sub mymethod : locked method;
    ...
    sub mymethod : locked method {
	...
    }

    sub othermethod :locked :method;
    ...
    sub othermethod :locked :method {
	...
    }

(请注意,只有第一个 : 是必需的,并且 : 周围的空格是可选的。)

AutoSplit.pmSelfLoader.pm 已更新,以保留它们提供的存根的属性。请参阅 attributes

文件和目录句柄可以自动生成

类似于 $x->[0] 等结构如何自动生成引用,句柄构造函数(open()、opendir()、pipe()、socketpair()、sysopen()、socket() 和 accept())现在如果传递给它们的句柄是未初始化标量变量,则会自动生成文件或目录句柄。这允许使用诸如 open(my $fh, ...)open(local $fh,...) 等结构来创建文件句柄,当作用域结束时,这些文件句柄将自动关闭,前提是没有其他引用。当必须传递文件句柄时,这在很大程度上消除了打开文件句柄时使用类型全局变量的需要,如下例所示

    sub myopen {
        open my $fh, "@_"
	     or die "Can't open '@_': $!";
	return $fh;
    }

    {
        my $f = myopen("</etc/motd");
	print <$f>;
	# $f implicitly closed here
    }

open() 带有多于两个参数

如果 open() 传递三个参数而不是两个参数,则第二个参数用作模式,第三个参数用作文件名。这主要用于防止传统双参数形式的意外魔术行为。请参阅 perlfunc 中的“open”

64 位支持

任何具有 64 位整数的平台

(1) natively as longs or ints
(2) via special compiler flags
(3) using long long or int64_t

都可以按如下方式使用“quad”(64 位整数)

请注意,除非您遇到情况 (a),否则您将必须使用 -Duse64bitint 配置标志来配置和编译 Perl。

NOTE: The Configure flags -Duselonglong and -Duse64bits have been
deprecated.  Use -Duse64bitint instead.

实际上有两种 64 位模式:第一种是使用 Configure -Duse64bitint 实现的,第二种是使用 Configure -Duse64bitall 实现的。不同之处在于,第一种模式是最小的,而第二种模式是最大的。第一种模式比第二种模式在更多地方起作用。

use64bitint 只执行将 64 位整数导入 Perl 所需的操作(例如,可能使用“long long”),而您的内存可能仍然限制在 2 GB(因为您的指针仍然可能是 32 位)。请注意,名称 64bitint 并不意味着您的 C 编译器将使用 64 位 int(它可能使用,但不必使用):use64bitint 意味着您将能够拥有 64 位宽标量值。

use64bitall 会尝试将整数(如果可以)、long(和指针)也切换为 64 位,从而一路进行到底。这可能会创建一个比 -Duse64bitint 二进制兼容性更差的 Perl:生成的执行文件可能根本无法在 32 位框中运行,或者您可能必须重新启动/重新配置/重建您的操作系统以支持 64 位。

像 Alpha 和 Cray 这样的原生 64 位系统既不需要 -Duse64bitint,也不需要 -Duse64bitall。

最后但并非最不重要的一点:请注意,由于 Perl 习惯于始终使用浮点数,因此 quads 仍然不是真正的整数。当 quads 溢出其限制(0...18_446_744_073_709_551_615 无符号,-9_223_372_036_854_775_808...9_223_372_036_854_775_807 有符号)时,它们会被静默提升为浮点数,之后它们将开始失去精度(在其较低位数中)。

NOTE: 64-bit support is still experimental on most platforms.
Existing support only covers the LP64 data model.  In particular, the
LLP64 data model is not yet supported.  64-bit libraries and system
APIs on many platforms have not stabilized--your mileage may vary.

大文件支持

如果您有支持“大文件”(大于 2 GB 的文件)的文件系统,您现在还可以从 Perl 创建和访问它们。

NOTE: The default action is to enable large file support, if
available on the platform.

如果启用了大文件支持,并且您有 Fcntl 常量 O_LARGEFILE,则 O_LARGEFILE 会自动添加到 sysopen() 的标志中。

请注意,除非您的文件系统还支持“稀疏文件”,否则不建议寻求数百 PB 的文件。

请注意,除了需要一个合适的文件系统来处理大文件之外,您可能还需要在运行尝试处理大文件的 Perl 脚本之前调整每个进程(或每个系统、每个进程组或每个用户组)的最大文件大小限制,尤其是如果您打算写入此类文件。

最后,除了您的进程/进程组的最大文件大小限制之外,您可能还有文件系统上的配额限制,阻止您(您的用户 ID 或您的用户组 ID)使用大文件。

调整您的进程/用户/组/文件系统/操作系统限制超出了 Perl 核心语言的范围。对于进程限制,您可以在运行 Perl 之前尝试使用 shell 的 limits/limit/ulimit 命令增加限制。BSD::Resource 扩展(不包含在标准 Perl 发行版中)也可能有用,它提供了 getrlimit/setrlimit 接口,可用于调整进程资源使用限制,包括最大文件大小限制。

长双精度

在某些系统中,您可以使用长双精度来增强双精度浮点数(即 Perl 的数字)的范围和精度。使用 Configure -Duselongdouble 来启用此支持(如果可用)。

"更多位"

您可以“Configure -Dusemorebits”来同时开启 64 位支持和长双精度支持。

sort() 子例程的增强支持

原型为 ($$) 的 Perl 子例程和 XSUB(一般而言)现在可以用作 sort 子例程。在任何一种情况下,要比较的两个元素都作为普通参数传递给 @_。请参阅 perlfunc 中的“sort”

对于未指定原型的 sort 子例程,将要比较的元素作为全局变量 $a 和 $b 传递的历史行为保持不变。

允许 sort $coderef @foo

在早期版本中,sort() 不接受子例程引用作为比较函数。现在允许这样做。

内部实现文件遍历

Perl 现在自动使用 File::Glob 实现 glob() 运算符。这避免了使用外部 csh 进程及其相关问题。

NOTE: This is currently an experimental feature.  Interfaces and
implementation are subject to change.

支持 CHECK 块

除了 BEGININITENDDESTROYAUTOLOAD 之外,名为 CHECK 的子例程现在也是特殊的。这些子例程在编译期间排队,其行为类似于 END 块,但它们是在编译结束时而不是在执行结束时被调用。无法直接调用它们。

支持 POSIX 字符类语法 [: :]

例如,要匹配字母字符,请使用 /[[:alpha:]]/。有关详细信息,请参阅 perlre

更好的伪随机数生成器

在 5.005_0x 及更早版本中,perl 的 rand() 函数使用 C 库 rand(3) 函数。从 5.005_52 开始,Configure 会依次测试 drand48()、random() 和 rand(),并选择找到的第一个函数。

这些更改应该会让 rand() 生成更好的随机数。

改进的 qw// 运算符

qw// 运算符现在在编译时计算为一个真列表,而不是替换为对 split() 的运行时调用。这消除了 qw// 在标量上下文中令人困惑的错误行为,该行为是从 split() 继承的。

因此

$foo = ($bar) = qw(a b c); print "$foo|$bar\n";

现在正确打印 "3|a",而不是 "2|a"。

哈希的更佳最坏情况行为

哈希算法中已实施小更改,以改善哈希值中低阶位的分布。这有望在重复序列的键上产生更好的性能。

支持 pack() 格式 'Z'

新格式类型 'Z' 对于打包和解包以空结尾的字符串很有用。请参阅 perlfunc 中的“pack”

支持 pack() 格式修饰符 '!'

新格式类型修饰符 '!' 对于打包和解包本机短整数、整数和长整数很有用。请参阅 perlfunc 中的“pack”

pack() 和 unpack() 支持计数字符串

模板字符 '/' 可用于指定要打包或解包的计数字符串类型。请参阅 perlfunc 中的“pack”

pack() 模板中的注释

模板中的 '#' 字符引入一行末尾的注释。这有助于 pack() 模板的文档化。

弱引用

在 Perl 的早期版本中,你无法缓存对象,以便在从缓存外部删除最后一个引用时允许删除它们。缓存中的引用将对对象保留引用计数,并且对象将永远不会被销毁。

另一个常见问题是循环引用。当一个对象引用自身时,其引用计数永远不会降至零,并且在程序即将退出之前不会被销毁。

弱引用通过允许你“弱化”任何引用(即使其不计入引用计数)来解决此问题。当对对象的最后一个非弱引用被删除时,对象将被销毁,并且对该对象的所有弱引用将自动取消定义。

要使用此功能,您需要 CPAN 中的 Devel::WeakRef 包,其中包含其他文档。

NOTE: This is an experimental feature.  Details are subject to change.  

支持二进制数

二进制数现在作为文字、s?printf 格式和 oct() 支持

$answer = 0b101010;
printf "The answer is: %b\n", oct("0b101010");

左值子例程

子例程现在可以返回可修改的左值。请参阅 "perlsub 中的“左值子例程”

NOTE: This is an experimental feature.  Details are subject to change.

通过引用进行调用时,某些箭头可以省略

Perl 现在允许在涉及通过引用进行子例程调用的许多构造中省略箭头。例如,$foo[10]->('foo') 现在可以写成 $foo[10]('foo')。这与从 $foo[10]->{'foo'} 中省略箭头的方式非常相似。但是,请注意,foo(10)->('bar') 仍然需要箭头。

现在允许使用诸如 ($a ||= 2) += 1 的构造。

exists() 支持子例程名称

exists() 内置函数现在适用于子例程名称。如果子例程已声明(即使是隐式声明),则认为它存在。有关示例,请参阅 "perlfunc 中的“exists”

exists() 和 delete() 支持数组元素

exists() 和 delete() 内置函数现在也适用于简单数组。行为类似于哈希元素。

exists() 可用于检查数组元素是否已初始化。这避免了对不存在的数组元素进行自动初始化。如果数组被绑定,则将调用相应绑定包中的 EXISTS() 方法。

delete() 可用于从数组中删除元素并返回它。该位置的数组元素返回到其未初始化状态,以便使用 exists() 测试同一元素将返回 false。如果碰巧是最后一个元素,则数组的大小也会缩小到对 exists() 测试为 true 的最高元素,或者如果找不到这样的元素,则缩小到 0。如果数组被绑定,则将调用相应绑定包中的 DELETE() 方法。

有关示例,请参阅 perlfunc 中的“exists”perlfunc 中的“delete”

伪哈希效果更好

意外地禁止了在伪哈希中取消引用某些类型的引用值,例如 $ph->{foo}[1]。此问题已得到纠正。

exists() 现在在应用于伪哈希元素时报告指定的值是否存在,而不仅仅是键是否有效。

delete() 现在适用于伪哈希。当给定一个伪哈希元素或切片时,它会删除与键对应的值(但不会删除键本身)。请参阅 perlref 中的“伪哈希:将数组用作哈希”

具有常量键的伪哈希切片现在经过优化,可在编译时进行数组查找。

现在支持对伪哈希切片进行列表赋值。

fields pragma 现在通过 fields::new() 和 fields::phash() 提供了创建伪哈希的方法。请参阅 fields

NOTE: The pseudo-hash data type continues to be experimental.
Limiting oneself to the interface elements provided by the
fields pragma will provide protection from any future changes.

自动刷新输出缓冲区

当尝试执行操作时,fork()、exec()、system()、qx// 和管道 open() 现在会刷新为输出打开的所有文件的缓冲区。这在很大程度上消除了用户遇到的令人困惑的缓冲失误,这些用户不知道 Perl 在内部如何处理 I/O。

在某些平台(如 Solaris)上不支持此功能,因为那里没有 fflush(NULL) 的正确实现。

对无意义的文件句柄操作进行更好的诊断

诸如 open(<FH>)close(<FH>) 之类的构造是编译时错误。尝试从仅为写入而打开的文件句柄中读取现在会产生警告(就像写入只读文件句柄一样)。

在可能的情况下,从复制的输入文件句柄中丢弃缓冲数据

open(NEW, "<&OLD") 现在尝试丢弃在复制句柄之前在 OLD 中读取并缓冲的任何数据。在允许执行此操作的平台上,对 NEW 的下一次读取操作将返回与对 OLD 的相应操作相同的数据。以前,它会返回下一个磁盘块开头的而不是数据。

eof() 具有与 <> 相同的旧魔术

如果尚未尝试从 <> 中读取,则 eof() 将返回 true。eof() 已更改为具有一些自己的魔术,现在它会打开 <> 文件。

binmode() 可用于设置 :crlf 和 :raw 模式

binmode() 现在接受第二个参数,该参数指定相关句柄的规则。目前在 DOS 派生平台上支持两个伪规则“:raw”和“:crlf”。请参阅 perlfunc 中的“binmode”open

-T filetest 识别 UTF-8 编码文件为“文本”

用于 -T filetest 的算法已得到增强,可正确识别 UTF-8 内容为“文本”。

system()、反引号和管道打开现在反映 exec() 失败

在 Unix 和类似平台上,system()、qx() 和 open(FOO, "cmd |") 等通过 fork() 和 exec() 实现。当底层 exec() 失败时,早期版本未正确报告错误,因为 exec() 碰巧在不同的进程中。

子进程现在与父进程通信,告知其启动外部命令时发生的错误,这允许这些构造返回其通常的错误值并设置 $!。

改进的诊断

在全局销毁阶段,行号不再被抑制(在大多数情况下)。

现在,从主线程以外的线程中运行的代码发出的诊断附带线程 ID。

诊断中嵌入的空字符现在实际显示。在以前的版本中,它们会截断消息。

$foo::a 和 $foo::b 现在仅当在包 foo 中遇到 sort() 时才免于“可能的错别字”警告。

现在,在解析引用构造时遇到的无法识别的字母转义字符会生成警告,因为它们在以后版本的 Perl 中可能会采用新的语义。

现在,许多诊断报告引发警告的内部操作,如下所示

Use of uninitialized value in concatenation (.) at (eval 1) line 1.
Use of uninitialized value in print at (eval 1) line 1.

在 eval 中发生的诊断还可能报告 eval 所在的文件和行号,以及 eval 序列号和已评估文本本身中的行号。例如

Not enough arguments for scalar at (eval 4)[newlib/perl5db.pl:1411] line 2, at EOF

诊断遵循 STDERR

诊断输出现在转到 STDERR 句柄指向的任何文件,而不是始终转到底层 C 运行时库的 stderr

更一致的 close-on-exec 行为

在支持文件句柄上设置 close-on-exec 标志的系统上,如果 $^F 的值需要,现在将为 pipe()、socketpair()、socket() 和 accept() 创建的任何句柄设置该标志。早期版本忽略了为使用这些运算符创建的句柄设置标志。请参阅 perlfunc 中的 "pipe""socketpair""socket""accept" 和 perlvar 中的 "$^F"

syswrite() 易用性

syswrite() 的长度参数已变为可选。

对带括号的一元运算符进行更好的语法检查

诸如

print defined(&foo,&bar,&baz);
print uc("foo","bar","baz");
undef($foo,&bar);

之类的表达式在早期版本中被意外允许,并产生了不可预测的行为。有些在以这种方式使用时产生了辅助警告;而另一些则默默地做错了事。

现在,大多数期望单个参数的一元运算符的带括号形式确保它们不会使用多个参数调用,从而使上面显示的案例成为语法错误。通常的行为

print defined &foo, &bar, &baz;
print uc "foo", "bar", "baz";
undef $foo, &bar;

保持不变。请参阅 perlop

位运算符支持完整的本机整数宽度

位运算符 (& | ^ ~ << >>) 现在在完整的本机整数宽度上操作(其确切大小可在 $Config{ivsize} 中获得)。例如,如果您的平台是本机 64 位或如果 Perl 已配置为使用 64 位整数,则这些操作将应用于 8 个字节(与 32 位平台上的 4 个字节相对)。为了便于移植,请务必屏蔽一元 ~ 结果中的多余位,例如 ~$x & 0xffffffff

改进的安全功能

更多潜在的不安全操作会污染其结果以提高安全性。

现在,getpwent()、getpwnam() 和 getpwuid() 返回的 passwdshell 字段已被污染,因为用户可以影响自己的加密密码和登录 shell。

由 shmread() 修改的变量以及 msgrcv()(及其面向对象的接口 IPC::SysV::Msg::rcv)返回的消息也会被污染,因为其他不受信任的进程可以出于自己的邪恶目的修改消息和共享内存段。

更具功能性的裸字原型 (*)

裸字原型已被合理化,使其能够用于覆盖接受裸字并以特殊方式解释它们的内置函数,例如 requiredo

现在,原型为 * 的参数在子例程中将显示为简单标量或类型全局的引用。请参阅 "perlsub 中的“原型”

requiredo 可以被覆盖

requiredo 'file' 操作可以通过将同名子例程导入到当前包(或通过将它们导入到 CORE::GLOBAL:: 命名空间中)在本地进行覆盖。覆盖 require 也会影响 use,前提是在编译时可见覆盖。请参阅 "perlsub 中的“覆盖内置函数”

$^X 变量现在可以拥有长度超过一个字符的名称

以前,$^X 与 ${"\cX"} 同义,但 $^XY 是一个语法错误。现在,以控制字符开头的变量名可以任意长。但是,出于兼容性原因,这些变量必须使用显式大括号编写,例如 ${^XY}${^XYZ} 与 ${"\cXYZ"} 同义。具有多个控制字符的变量名(例如 ${^XY^Z})是非法的。

旧语法没有改变。与以前一样,`^X' 可以是文字控制-X 字符,也可以是两个字符序列“插入符号”加上“X”。当省略大括号时,变量名在控制字符后停止。因此,"$^XYZ" 仍然与以前一样继续与 $^X . "YZ" 同义。

与以前一样,词法变量的名称不能以控制字符开头。与以前一样,名称以控制字符开头的变量始终强制位于包 `main` 中。除了以 ^_ 开头的变量外,所有此类变量都保留给未来的扩展,用户程序可以使用这些变量,并且保证它们在任何未来版本的 Perl 中都不会获得特殊含义。

新变量 $^C 反映 -c 开关

$^C 具有布尔值,它反映 perl 是否在仅编译模式下运行(即通过 -c 开关)。由于 BEGIN 块在这样的条件下执行,因此此变量使 perl 代码能够确定在正常运行期间才有意义的操作是否有道理。请参阅 perlvar

新变量 $^V 包含 Perl 版本作为字符串

$^V 包含 Perl 版本号,该版本号为一个字符串,由其序数与版本号匹配的字符组成,即 v5.6.0。这可用于字符串比较。

请参阅 Support for strings represented as a vector of ordinals 了解示例。

可选的 Y2K 警告

如果 Perl 是使用已定义的 cpp 宏 PERL_Y2KWARN 构建的,那么在将数字 19 与其他数字连接时,它会发出可选的警告。

在运行 Configure 时必须特别启用此行为。请参阅 INSTALLREADME.Y2K

数组现在始终内插到双引号字符串中

在双引号字符串中,数组现在内插,无论如何。在早期版本的 perl 5 中的行为是,如果在编译字符串之前提到了数组,则数组将内插到字符串中,否则 Perl 会引发一个致命的编译时错误。在 5.000 到 5.003 版本中,错误是

Literal @example now requires backslash

在 5.004_01 到 5.6.0 版本中,错误是

In string, @example now must be written as \@example

这里的想法是让人们养成在需要文字 @ 符号时编写 "fred\@example.com" 的习惯,就像他们一直编写 "Give me back my \$5" 以获取文字 $ 符号一样。

从 5.6.1 开始,当 Perl 现在在双引号字符串中看到 @ 符号时,它始终尝试内插数组,无论该数组是否已经使用或声明。致命错误已降级为可选警告

Possible unintended interpolation of @example in string

这会警告您,如果您不使用反斜杠转义 @,则 "[email protected]" 将变为 fred.com。请参阅 http://perl.plover.com/at-error.html 了解有关此处历史的更多详细信息。

@- 和 @+ 提供正则表达式匹配的起始/结束偏移量

新魔术变量 @- 和 @+ 分别提供 $&、$1、$2 等等的起始偏移和结束偏移。有关详细信息,请参阅 perlvar

模块和实用程序

模块

属性

虽然 Perl 在内部将此模块用作实用程序,但它还提供了一种获取子例程和变量属性的方法。请参阅 attributes

B

Perl 编译器套件已针对此版本进行了大规模的重新设计。在编译器下运行时,更多标准 Perl 测试套件通过,但要实现生产质量的已编译可执行文件,还有很长的路要走。

NOTE: The Compiler suite remains highly experimental.  The
generated code may not be correct, even when it manages to execute
without errors.
基准

总体而言,基准结果表现出更低的平均误差和更好的计时精度。

现在,您可以运行测试 n 秒,而不必猜测要运行的测试的正确数量:例如,timethese(-5, ...) 将针对每个代码运行至少 5 个 CPU 秒。将“重复次数”设为零表示“至少 3 个 CPU 秒”。输出格式也已更改。例如

use Benchmark;$x=3;timethese(-5,{a=>sub{$x*$x},b=>sub{$x**2}})

现在将输出类似以下内容

Benchmark: running a, b, each for at least 5 CPU seconds...
         a:  5 wallclock secs ( 5.77 usr +  0.00 sys =  5.77 CPU) @ 200551.91/s (n=1156516)
         b:  4 wallclock secs ( 5.00 usr +  0.02 sys =  5.02 CPU) @ 159605.18/s (n=800686)

新功能:“每个至少 N 个 CPU 秒...”、“时钟秒”和“@ 操作/CPU 秒 (n=操作)”。

timethese() 现在返回对包含测试结果的基准对象哈希的引用,其键是测试的名称。

timethis() 现在返回基准结果对象中的迭代字段,而不是 0。

timethese()、timethis() 和新的 cmpthese()(见下文)还可以采用格式说明符“none”来禁止输出。

新函数 countit() 与 timeit() 类似,只是它采用 TIME 而不是 COUNT。

新函数 cmpthese() 打印一个图表,比较从 timethese() 调用返回的每个测试的结果。对于每对可能的测试,都会显示百分比速度差异(迭代/秒或秒/迭代)。

有关其他详细信息,请参阅 基准

ByteLoader

ByteLoader 是一个专门的扩展,用于生成和运行 Perl 字节码。请参阅 ByteLoader

常量

现在可以使用引用。

新版本还允许常量名称中出现前导下划线,但禁止出现双前导下划线(如 "__LINE__")。还禁止或警告使用某些其他名称,包括 BEGIN、END 等。以前强制放入 main:: 的某些名称在某些情况下会静默失败;现在它们是致命的(在 main:: 之外),并且是可选警告(在 main:: 之内)。已添加检测常量是否已使用给定名称设置的能力。

参见 constant

charnames

此编译指示实现 \N 字符串转义。参见 charnames

Data::Dumper

可以指定 Maxdepth 设置,以避免深入到深层数据结构中。参见 Data::Dumper

如果未使用 Useqq 设置,现在会自动调用 Dump() 的 XSUB 实现。

转储 qr// 对象可以正常工作。

DB

DB 是一个实验性模块,它公开了 Perl 调试 API 的干净抽象。

DB_File

现在可以使用 Berkeley DB 版本 1、2 或 3 构建 DB_File。参见 ext/DB_File/Changes

Devel::DProf

已添加 Devel::DProf,一个 Perl 源代码分析器。参见 Devel::DProfdprofpp

Devel::Peek

Devel::Peek 模块提供对 Perl 变量和数据的内部表示形式的访问。它是 XS 编程人员的数据调试工具。

Dumpvalue

Dumpvalue 模块提供 Perl 数据的屏幕转储。

DynaLoader

DynaLoader 现在支持在支持使用 dlclose() 卸载共享对象的平台上使用 dl_unload_file() 函数。

Perl 还可以选择安排卸载 Perl 加载的所有扩展共享对象。要启用此功能,请使用 Configure 选项 -Accflags=-DDL_UNLOAD_ALL_AT_EXIT 构建 Perl。(如果您将 Apache 与 mod_perl 一起使用,这可能很有用。)

English

$PERL_VERSION 现在代表 $^V(一个字符串值),而不是 $](一个数字值)。

Env

Env 现在支持将环境变量(如 PATH)访问为数组变量。

Fcntl

添加了更多 Fcntl 常量:F_SETLK64、F_SETLKW64、O_LARGEFILE,用于访问大文件(超过 4GB)(注意:如果已配置大文件支持,则会自动将 O_LARGEFILE 添加到 sysopen() 标志中,这是默认设置)、Free/Net/OpenBSD 锁定行为标志 F_FLOCK、F_POSIX、Linux F_SHLCK 和 O_ACCMODE:O_RDONLY、O_WRONLY 和 O_RDWR 的组合掩码。seek()/sysseek() 常量 SEEK_SET、SEEK_CUR 和 SEEK_END 可通过 :seek 标记获得。chmod()/stat() S_IF* 常量和 S_IS* 函数可通过 :mode 标记获得。

File::Compare

已添加 compare_text() 函数,它允许自定义比较函数。请参阅 File::Compare

File::Find

当 wanted() 函数被自动加载或为符号引用时,File::Find 现在可以正常工作。

已修复在修剪顶级目录时导致 File::Find 丢失工作目录的错误。

File::Find 现在还支持其他几个选项来控制其行为。如果指定了 follow 选项,它可以跟随符号链接。启用 no_chdir 选项将使 File::Find 在遍历目录时跳过更改当前目录。启用污点检查时,untaint 标志可能很有用。

请参阅 File::Find

File::Glob

此扩展实现了 BSD 样式的文件通配符。默认情况下,它还将用于 glob() 运算符的内部实现。请参阅 File::Glob

File::Spec

已向 File::Spec 模块添加新方法:devnull() 返回空设备的名称(在 Unix 上为 /dev/null),tmpdir() 返回临时目录的名称(在 Unix 上通常为 /tmp)。现在还有方法可在绝对文件名和相对文件名之间进行转换:abs2rel() 和 rel2abs()。为了与在文件路径中指定卷名的操作系统兼容,已添加了 splitpath()、splitdir() 和 catdir() 方法。

File::Spec::Functions

新的 File::Spec::Functions 模块为 File::Spec 模块提供了一个函数接口。允许使用简写

$fullname = catfile($dir1, $dir2, $file);

代替

$fullname = File::Spec->catfile($dir1, $dir2, $file);
Getopt::Long

Getopt::Long 许可已更改,允许 Perl 艺术许可以及 GPL。以前仅为 GPL,这妨碍了想要使用 Getopt::Long 的非 GPL 应用程序。

Getopt::Long 鼓励使用 Pod::Usage 来生成帮助消息。例如

use Getopt::Long;
use Pod::Usage;
my $man = 0;
my $help = 0;
GetOptions('help|?' => \$help, man => \$man) or pod2usage(2);
pod2usage(1) if $help;
pod2usage(-exitstatus => 0, -verbose => 2) if $man;

__END__

=head1 NAME

sample - Using Getopt::Long and Pod::Usage

=head1 SYNOPSIS

sample [options] [file ...]

 Options:
   -help            brief help message
   -man             full documentation

=head1 OPTIONS

=over 8

=item B<-help>

Print a brief help message and exits.

=item B<-man>

Prints the manual page and exits.

=back

=head1 DESCRIPTION

B<This program> will read the given input file(s) and do something
useful with the contents thereof.

=cut

有关详细信息,请参见 Pod::Usage

已修复阻止将非选项回调 <> 指定为第一个参数的错误。

要将字符 < 和 > 指定为选项启动器,请使用 ><。但请注意,强烈建议不要更改选项启动器。

IO

为了与 Perl 的 syswrite() 保持一致,write() 和 syswrite() 现在将接受调用的单参数形式。

您现在可以在不强制连接尝试的情况下创建基于 TCP 的 IO::Socket::INET。这允许您配置其选项(如使其变为非阻塞),然后手动调用 connect()。

已更正阻止 IO::Socket::protocol() 访问器返回正确值的错误。

IO::Socket::connect 现在使用非阻塞 IO 代替 alarm() 来执行连接超时。

IO::Socket::accept 现在使用 select() 代替 alarm() 来执行超时。

IO::Socket::INET->new 现在在失败时正确设置 $!。$@ 仍设置为向后兼容。

JPL

Java Perl Lingo 现在随 Perl 一起分发。有关更多信息,请参见 jpl/README。

lib

use lib 现在会清除任何尾部重复条目。no lib 会删除所有已命名的条目。

Math::BigInt

位运算 <<>>&|~ 现在支持 bigint。

Math::Complex

访问器方法 Re、Im、arg、abs、rho 和 theta 现在也可以充当变异器(访问器 $z->Re(),变异器 $z->Re(3))。

类方法 display_format 和相应对象方法 display_format,除了接受一个参数外,现在还可以接受一个参数哈希。参数哈希的识别键为 "style",它对应于旧的一个参数情况,以及两个新参数:"format",它是一个 printf() 样式的格式化字符串(通常默认为 "%.15g",您可以通过将格式化字符串设置为 undef 来还原为默认值),用于复数的两个部分,以及 "polar_pretty_print"(默认为 true),它控制是否尝试识别极复数的参数(角度)处 pi(2pi、pi/2)的小倍数和有理数。

潜在的破坏性更改是,在列表上下文中,这两个方法现在返回参数哈希,而不仅仅是 "style" 参数的值。

Math::Trig

添加了一点径向三角学(圆柱形和球形)、径向坐标转换和最大圆距离。

Pod::Parser、Pod::InputObjects

Pod::Parser 是一个基类,用于从输入流中解析和选择 pod 文档的章节。此模块负责识别输入中的 pod 段落和命令,并将解析后的段落和命令传递给用户定义的方法,这些方法可以自由地解释或翻译它们,视情况而定。

Pod::InputObjects 定义了 Pod::Parser 所需的一些输入对象,以及对于需要除了名称和文本之外的更多命令的高级 Pod::Parser 用户。

从 Perl 的 5.6.0 版本开始,Pod::Parser 现在是官方认可的“基本解析器代码”,建议所有 pod2xxx 翻译器使用。Pod::Text (pod2text) 和 Pod::Man (pod2man) 已转换为使用 Pod::Parser,并且正在进行将 Pod::HTML (pod2html) 转换为使用 Pod::Parser 的工作。对于有关 pod 解析和翻译问题和实用工具的任何问题或意见,请使用 [email protected] 邮件列表。

有关更多信息,请参阅 Pod::ParserPod::InputObjects

Pod::Checker、podchecker

此实用工具根据 perlpod 检查 pod 文件的语法是否正确。明显的错误会被标记为错误,而对于可以正常处理的错误,则会打印警告。该清单尚未完成。请参阅 Pod::Checker

Pod::ParseUtils、Pod::Find

这些模块提供了一组小工具,主要对 pod 翻译器有用。Pod::Find 遍历目录结构并返回找到的 pod 文件及其规范名称(如 File::Spec::Unix)。Pod::ParseUtils 包含 Pod::List(用于存储 pod 列表信息)、Pod::Hyperlink(用于解析 L<> 序列的内容)和 Pod::Cache(用于缓存有关 pod 文件的信息,例如链接节点)。

Pod::Select、podselect

Pod::Select 是 Pod::Parser 的一个子类,它提供了一个名为“podselect()”的函数,用于从输入流中筛选出用户指定的原始 pod 文档部分。podselect 是一个脚本,它允许从其他脚本中访问 Pod::Select 以用作过滤器。请参阅 Pod::Select

Pod::Usage,pod2usage

Pod::Usage 提供“pod2usage()”函数,用于根据嵌入的 pod 文档打印 Perl 脚本的用法消息。pod2usage() 函数通常对所有脚本作者都很有用,因为它允许他们为文档编写并维护一个单一来源(pod),从而无需创建和维护冗余的用法消息文本,其中包含 pod 中已有的信息。

还有一个 pod2usage 脚本,可用于其他类型的脚本,以便从 pod 打印用法消息(即使对于在注释中嵌入 pod 的非 Perl 脚本也是如此)。

有关详细信息和示例,请参阅 Pod::Usage

Pod::Text 和 Pod::Man

Pod::Text 已被重写为使用 Pod::Parser。虽然 pod2text() 仍可用于向后兼容,但该模块现在有一个新的首选接口。有关详细信息,请参阅 Pod::Text。新的 Pod::Text 模块很容易进行子类化以调整输出,并且现在有两个这样的子类(Pod::Text::Termcap 用于使用术语表信息进行手册页样式的加粗和下划线,以及 Pod::Text::Color 用于使用 ANSI 颜色序列进行标记)。

pod2man 已变成一个模块 Pod::Man,它也使用 Pod::Parser。在此过程中,已修复了几个与章节标题中的引号、代码转义符的引用和嵌套列表相关的突出错误。pod2man 现在是围绕此模块的一个包装器脚本。

SDBM_File

已向此模块添加 EXISTS 方法(并且已向底层 sdbm 库添加 sdbm_exists()),因此现在可以在 SDBM_File 绑定的哈希上调用 exists 并获得正确的结果,而不是运行时错误。

已修复一个错误,该错误可能导致在单个 FETCH() 中从数据库读取多个磁盘块时丢失数据。

Sys::Syslog

Sys::Syslog 现在使用 XSUB 从 syslog.h 访问设施,因此它不再需要 syslog.ph 存在。

Sys::Hostname

Sys::Hostname 现在使用 XSUB 调用 C 库的 gethostname() 或 uname()(如果它们存在)。

Term::ANSIColor

Term::ANSIColor 是一个非常简单的模块,可以轻松且可读地访问 ANSI 颜色和突出显示转义序列,大多数 ANSI 终端仿真器支持这些序列。它现在已包含在标准中。

Time::Local

当日期超出机器的整数范围时,timelocal() 和 timegm() 函数过去常常在不提示的情况下返回虚假结果。如果日期落在不受支持的范围内,它们现在会始终 croak()。

Win32

已更改返回值列表的所有函数的错误返回值。以前,如果发生错误,这些函数会返回一个包含单个元素 undef 的列表。现在,在这些情况下,这些函数返回空列表。这适用于以下函数

Win32::FsType
Win32::GetOSVersion

剩余函数保持不变,在列表上下文中,即使出错,也会继续返回 undef

Win32::SetLastError(ERROR) 函数已作为 Win32::GetLastError() 函数的补充添加。

新的 Win32::GetFullPathName(FILENAME) 在标量上下文中返回 FILENAME 的完整绝对路径名。在列表上下文中,它返回一个包含完全限定目录名和文件名的双元素列表。请参阅 Win32

XSLoader

XSLoader 扩展是 DynaLoader 的一个更简单的替代方案。请参阅 XSLoader

DBM 过滤器

一个名为“DBM 过滤器”的新功能已添加到所有 DBM 模块——DB_File、GDBM_File、NDBM_File、ODBM_File 和 SDBM_File。DBM 过滤器为每个 DBM 模块添加了四种新方法

filter_store_key
filter_store_value
filter_fetch_key
filter_fetch_value

这些方法可用于在键值对写入数据库之前或刚从数据库读取后对其进行筛选。有关详细信息,请参阅 perldbmfilter

Pragmata

use attrs 现在已过时,仅出于向后兼容性而提供。它已被 sub : attributes 语法替换。请参阅 "perlsub 中的“子例程属性”attributes

词法警告 Pragmata,use warnings;,用于控制可选警告。请参阅 perllexwarn

use filetest 用于控制文件测试的行为(-r -w ...)。目前仅实现了一个子 Pragmata,“use filetest 'access';”,它使用 access(2) 或等效项来检查权限,而不是像往常一样使用 stat(2)。这在具有 ACL(访问控制列表)的文件系统中很重要:stat(2) 可能会撒谎,但 access(2) 更了解情况。

open Pragmata 可用于指定句柄构造函数(例如 open())和 qx// 的默认规则。目前在 DOS 派生平台上支持两个伪规则 :raw:crlf(即 binmode 不是无操作)。另请参阅 "binmode() 可用于设置 :crlf 和 :raw 模式"

实用程序更改

dprofpp

dprofpp 用于显示使用 Devel::DProf 生成的配置文件数据。请参阅 dprofpp

find2perl

find2perl 实用工具现在使用 File::Find 模块的增强功能。支持 -depth 和 -follow 选项。脚本中还包含 Pod 文档。

h2xs

h2xs 工具现在可以与 C::Scan(可从 CPAN 获得)结合使用,以自动解析实际的头文件。-M-a-k-o 选项是新增的。

perlcc

perlcc 现在支持 C 和字节码后端。默认情况下,它会生成简单 C 后端而不是优化 C 后端的输出。

对非 Unix 平台的支持已得到改进。

perldoc

perldoc 已被重新设计,以避免可能的安全漏洞。它不会默认允许自身作为超级用户运行,但你仍然可以使用 -U 开关尝试首先使其放弃特权。

Perl 调试器

Perl 调试器 perl5db.pl 中添加了许多错误修复和增强功能。帮助文档已重新整理。新命令包括 < ?> ?{ ?,用于列出当前操作,man docpage 在某些 perl 文档集上运行文档查看器,以及对带引号选项的支持。帮助信息已重新整理,如果你使用 less 作为分页器,应该可以再次查看。一个严重的漏洞已被修复——你应该立即从系统中删除所有较旧版本的 Perl 调试器,这些版本已安装在以前的版本中,一直可以追溯到 perl3,以避免受到此漏洞的攻击。

改进的文档

现在,许多特定于平台的自述文件都是 perl 安装的一部分。请参阅 perl 了解完整列表。

perlapi.pod

Perl 公共 API 函数的官方列表。

perlboot.pod

面向面向对象 Perl 初学者的教程。

perlcompile.pod

Perl 编译器套件使用入门。

perldbmfilter.pod

有关如何使用 DBM 筛选器工具的指南文档。

perldebug.pod

所有与运行 Perl 调试器无关的材料,以及所有可能让调试器的普通用户感到困惑的底层细节,已从旧手册页移至下面的下一个条目。

perldebguts.pod

这个新的手册页包含与 Perl 调试器无关的过多的底层材料,但与调试 Perl 本身略有关系。它还包含一些调试过程如何工作的深奥内部细节,这些细节可能只对 Perl 调试器的开发人员感兴趣。

perlfork.pod

当前可用于 Windows 平台的 fork() 仿真说明。

perlfilter.pod

编写 Perl 源代码过滤器的简介。

perlhack.pod

一些有关破解 Perl 源代码的准则。

perlintern.pod

Perl 源代码中的内部函数列表。(列表当前为空。)

perllexwarn.pod

词法作用域警告类别的简介和参考信息。

perlnumber.pod

有关在 Perl 中表示的数字的详细信息。

perlopentut.pod

有关有效使用 open() 的教程。

perlreftut.pod

介绍引用基本知识的教程。

perltootc.pod

有关管理对象模块类数据的教程。

perltodo.pod

讨论 Perl 中可能有一天得到支持的最常需要的特性。

perlunicode.pod

Perl 中 Unicode 支持特性的简介。

性能增强

使用 { $a <=> $b } 等的简单 sort() 已优化

现在,许多使用简单内联块的常见 sort() 操作都已针对更快的性能进行了优化。

对词法变量的优化赋值

赋值语句的 RHS 中的某些操作已优化,以便直接设置 LHS 上的词法变量,从而消除了冗余的复制开销。

更快的子例程调用

在内部处理子例程调用方式上的细微更改可带来边际性能提升。

delete()、each()、values() 和哈希迭代速度更快

delete()、each()、values() 和列表上下文中哈希返回的哈希值是哈希中的实际值,而不是副本。这显著提高了性能,因为它在大多数情况下消除了不必要的复制。

安装和配置改进

-Dusethreads 表示其他含义

-Dusethreads 标志现在默认启用基于解释器的实验性线程支持。相反,要获得 5.005 中的实验性线程,您需要使用“-Dusethreads -Duse5005threads”运行 Configure。

从 v5.6.0 开始,解释器线程支持仍然缺少一种从 Perl 创建新线程的方法(即,use Thread; 将不适用于解释器线程)。当您为 Configure 指定 -Duse5005threads 选项时,use Thread; 仍然可用,包括所有错误。

NOTE: Support for threads continues to be an experimental feature.
Interfaces and implementation are subject to sudden and drastic changes.

新的 Configure 标志

以下新标志可以通过使用 -Dflag 运行 Configure 在 Configure 命令行中启用。

usemultiplicity
usethreads useithreads	(new interpreter threads: no Perl API yet)
usethreads use5005threads	(threads as they were in 5.005)

use64bitint			(equal to now deprecated 'use64bits')
use64bitall

uselongdouble
usemorebits
uselargefiles
usesocks			(only SOCKS v5 supported)

多线程和 64 位现在更加大胆

启用线程使用和 64 位使用的 Configure 选项现在更加大胆,因为它们不再具有已知线程/64 位功能的操作系统的显式列表。换句话说:如果您的操作系统具有必要的 API 和数据类型,您应该能够继续使用它们,对于线程,通过 Configure -Dusethreads,对于 64 位,通过 Configure -Duse64bitint 显式使用,或者如果您的系统具有 64 位宽数据类型,则隐式使用。另请参见“64 位支持”

长双精度

一些平台具有“长双精度”,即浮点数的范围比普通“双精度”更大。要启用对 Perl 标量的长双精度使用,请使用 -Duselongdouble。

-Dusemorebits

您可以使用 -Dusemorebits 启用 -Duse64bitint 和 -Duselongdouble。另请参见“64 位支持”

-Duselargefiles

一些平台支持能够处理大文件(通常,大于 2 GB 的文件)的系统 API。如果您要求 -Duselargefiles,Perl 将尝试使用这些 API。

有关详细信息,请参阅 “大文件支持”

installusrbinperl

您可以使用“Configure -Uinstallusrbinperl”,这会导致 installperl 跳过将 perl 也安装为 /usr/bin/perl。如果您出于某种原因不想修改 /usr/bin,这很有用,但有害,因为许多脚本假定在 /usr/bin/perl 中找到 Perl。

SOCKS 支持

您可以使用“Configure -Dusesocks”,这会导致 Perl 探测 SOCKS 代理协议库(v5,而不是 v4)。有关 SOCKS 的更多信息,请参阅

http://www.socks.nec.com/

-A 标志

您可以使用 Configure -A 开关“后期编辑”Configure 变量。编辑会在处理特定于平台的提示文件后立即发生,但在实际配置过程开始之前。运行 Configure -h 以了解完整的 -A 语法。

增强的安装目录

安装结构已经得到丰富,以改进对维护多个 perl 版本的支持,为供应商提供的模块、脚本和手册页提供位置,并简化对本地添加的模块、脚本和手册页的维护。有关完整详细信息,请参阅 INSTALL 文件中的安装目录部分。对于大多数从源代码构建和安装的用户,默认值应该很好。

如果您以前使用 Configure -Dsitelib-Dsitearch 为库目录设置特殊值,您可能希望考虑改用新的 -Dsiteprefix 设置。此外,如果您希望重新使用来自 perl 早期版本的 config.sh 文件,则应确保 Configure 为新目录做出明智的选择。有关完整详细信息,请参阅 INSTALL。

特定于平台的更改

受支持的平台

DOS

OS390(OpenEdition MVS)

此版本中尚未更新对该 EBCDIC 平台的支持。由于两者不兼容,因此难以协调 Perl 标准化其内部字符表示形式 UTF-8 与 EBCDIC 字符集。

目前尚不清楚未来版本是否会重新支持此平台,但存在这种可能性。

VMS

对配置、构建、测试和安装过程进行了大量修订和扩展,以适应核心更改和 VMS 特定的选项。

扩展 %ENV 处理代码,以允许在运行时映射到逻辑名称、CLI 符号和 CRTL 环境数组。

扩展子进程调用代码以接受文件规范作为命令“动词”。

添加到 Perl 命令行处理中,使其能够使用默认文件类型并识别 Unix 样式的 2>&1

扩展 File::Spec::VMS 例程,并将其集成到 ExtUtils::MM_VMS 中。

扩展 ExtUtils::MM_VMS 以更灵活地处理复杂扩展。

Unix 语法路径开头的裸字可以被视为文本,而不仅仅是逻辑名称。

可选地安全翻译 Perl 内部使用的几个逻辑名称。

对新核心代码进行杂项错误修复和移植到 VMS。

非常感谢为 VMS 补丁、测试和想法做出贡献的众多人士。

Win32

Perl 现在可以在内部模拟 fork(),使用在不同并发线程中运行的多个解释器。此支持必须在构建时启用。有关详细信息,请参见 perlfork

当给定仅由驱动器名称组成的路径名(例如 A:)时,opendir() 和 stat() 现在使用驱动器的当前工作目录,而不是驱动器根目录。

Win32:: 命名空间中的内置 XSUB 函数已记录。请参见 Win32

$^X 现在包含正在运行的可执行文件的完整路径名。

提供 Win32::GetLongPathName() 函数以补充 Win32::GetFullPathName() 和 Win32::GetShortPathName()。请参见 Win32

支持 POSIX::uname()。

system(1,...) 现在返回真正的进程 ID,而不是进程句柄。kill() 接受任何真实的进程 ID,而不仅仅是 system(1,...) 的返回值。

为了更好地与 Unix 兼容,现在可以使用 kill(0, $pid) 来测试进程是否存在。

支持 Shell 模块。

已添加对在 Windows 95 中的 command.com 下构建 Perl 的更好的支持。

默认情况下,脚本以二进制模式读取,以允许 ByteLoader(以及一般的筛选机制)正常工作。为了兼容性,如果在包含 __END__ 或 __DATA__ 令牌的行末检测到回车,则 DATA 文件句柄将被设置为文本模式;如果没有,则 DATA 文件句柄将保持在二进制模式下打开。早期版本始终以文本模式打开 DATA 文件句柄。

glob() 运算符通过 File::Glob 扩展实现,该扩展支持 C shell 的 glob 语法。这增加了 glob() 运算符的灵活性,但对于依赖于旧 glob 语法的程序来说,可能会出现兼容性问题。如果您希望保留与旧语法的兼容性,则可能需要使用 -MFile::DosGlob 运行 perl。有关详细信息和兼容性信息,请参阅 File::Glob

重大错误修复

<HANDLE> 在空文件中

$/ 设置为 undef 后,“读取”空文件会在第一次在将 $/ 设置为 undef 后读取 HANDLE 时返回一个长度为零的字符串(而不是像以前那样的 undef)。进一步的读取会产生 undef

这意味着以下内容会将“foo”追加到空文件中(以前什么也不做)

perl -0777 -pi -e 's/^/foo/' empty_file

的行为

perl -pi -e 's/^/foo/' empty_file

保持不变(它继续使文件保持为空)。

eval '...' 改进

涉及 here 文档时,eval '...' 中的行号(由 caller() 和大多数诊断反映)通常不正确。此问题已得到纠正。

eval '...' 中调用的函数中出现的变量的词法查找在错误的位置搜索词法。词法搜索现在正确地结束于子例程的块边界。

eval {...} 中使用 return 会导致在 eval 中未发生异常时 $@ 未正确重置。此问题已得到修复。

当 here 文档作为 eval 's/.../.../e' 中的替换表达式出现时,对它们的解析存在缺陷。此问题已得到修复。

所有编译错误都是真正的错误

编译时遇到的某些“错误”必须生成为警告,然后最终终止程序。这使得在单次运行中报告更多此类错误成为可能,而不是在遇到的第一个错误时导致强制停止。

报告此类错误的机制已重新实现,以对编译时错误进行排队,并在编译结束时将它们报告为真正的错误,而不是警告。这修复了在使用 eval STRING 在运行时编译代码时,错误消息以警告形式泄漏的情况,还允许使用 eval "..." 可靠地捕获此类错误。

隐式关闭的文件句柄更安全

有时,隐式关闭的文件句柄(例如在它们被本地化时,Perl 会在退出范围时自动关闭它们)可能会无意中设置 $? 或 $!。此问题已得到纠正。

列表切片的行为更一致

在获取字面列表的切片(相对于数组或哈希的切片)时,如果结果碰巧由所有未定义值组成,Perl 过去会返回一个空列表。

新行为是在(且仅在)原始列表为空时生成一个空列表。考虑以下示例

@a = (1,undef,undef,2)[2,1,2];

旧行为会导致 @a 没有元素。新行为确保它有三个未定义元素。

特别注意,以下情况的切片行为保持不变

@a = ()[1,2];
@a = (getpwent)[7,0];
@a = (anything_returning_empty_list())[2,1,2];
@a = @b[2,1,2];
@a = @c{'a','b','c'};

请参阅 perldata

(\$) 原型和 $foo{a}

标量引用原型现在正确允许在该槽中使用哈希或数组元素。

goto &sub 和 AUTOLOAD

&sub 碰巧被自动加载时,goto &sub 构造正确工作。

-bareword 允许在 use integer

在启用 integer pragma 时,先前由 - 前缀的裸字的自动引用不起作用。此问题已得到修复。

DESTROY() 中的失败

当析构函数中的代码引发异常时,在早期版本的 Perl 中不会注意到它,除非有人碰巧在析构函数运行后立即查看 $@。当启用警告时,此类失败现在会显示为警告。

已修复区域设置错误

printf() 和 sprintf() 以前将数字区域设置重置回默认的“C”区域设置。此问题已得到修复。

按照本地数字区域设置格式化的数字(例如使用小数逗号而不是小数点)会导致“不是数字”警告,即使访问这些数字的操作产生了正确的结果。这些警告已停止。

内存泄漏

eval 'return sub {...}' 构造有时会泄漏内存。此问题已修复。

在无效文件句柄上使用非文件句柄构造的操作过去会泄漏内存。此问题已修复。

修改 @_ 的构造可能无法释放 @_ 中的值,从而导致内存泄漏。此问题已更正。

子例程调用失败后出现虚假子例程存根

当在包中找不到子例程时,Perl 有时会创建空子例程存根。此类情况会阻止后续方法查找进入基包。此问题已更正。

-U 下的污染失败

在不安全模式下运行时,污染违规有时会导致静默失败。此问题已修复。

END 块和 -c 开关

当 Perl 在仅编译模式下运行时,早期版本过去常常运行 BEGIN END 块。由于这通常不是预期的行为,因此在使用 -c 开关或编译失败时,不再执行 END 块。

有关如何在编译阶段结束时运行内容,请参见 "支持 CHECK 块"

泄漏 DATA 文件句柄的可能性

使用 __DATA__ 标记会创建到包含该标记的文件的隐式文件句柄。程序有责任在完成读取后将其关闭。

此警告现在在文档中得到了更好的解释。请参见 perldata

新增或更改的诊断

"%s" 变量 %s 掩盖了在同一 %s 中的早期声明

(W misc) 已在当前作用域或语句中重新声明“my”或“our”变量,有效地消除了对先前实例的所有访问。这几乎总是错字。请注意,较早的变量仍将存在,直到作用域结束或对其的所有闭包引用被销毁为止。

尚未实现“my sub”

(F) 尚未实现词法作用域子例程。请勿尝试。

“我们”的变量 %s 重新声明

(W misc) 您似乎已在当前词法范围内之前声明过一次相同的全局变量。

'!' 仅在类型 %s 后允许

(F) '!' 仅在某些类型后才允许在 pack() 和 unpack() 中使用。请参阅 perlfunc 中的“pack”

/ 无法获取计数

(F) 您有一个解包模板,指示一个计数长度的字符串,但您还为该字符串指定了一个显式大小。请参阅 perlfunc 中的“pack”

/ 必须后跟 a、A 或 Z

(F) 您有一个解包模板,指示一个计数长度的字符串,该字符串必须后跟字母 a、A 或 Z 之一,以指示要解包的字符串类型。请参阅 perlfunc 中的“pack”

/ 必须后跟 a*、A* 或 Z*

(F) 您有一个打包模板,指示一个计数长度的字符串,目前唯一可以计数长度的是 a*、A* 或 Z*。请参阅 perlfunc 中的“pack”

/ 必须后跟一个数字类型

(F) 您有一个解包模板,其中包含一个 '#”,但它没有遵循一些数字解包规范。请参阅 perlfunc 中的“pack”

/%s/: 传递了无法识别的转义字符 \\%c

(W regexp) 您使用了一个 Perl 无法识别的反斜杠字符组合。此组合出现在内插变量或以 ' 分隔的正则表达式中。该字符被理解为字面意思。

/%s/: 传递了字符类中无法识别的转义字符 \\%c

(W regexp) 您在字符类中使用了一个 Perl 无法识别的反斜杠字符组合。该字符被理解为字面意思。

/%s/ 可能应该写成 "%s"

(W syntax) 您使用了一个 Perl 期望找到字符串的模式,例如 join 的第一个参数。Perl 会将根据 $_ 匹配模式的真或假结果视为字符串,这可能不是您所想的。

%s() 调用得太早,无法检查原型

(W 原型)您调用了一个在解析器看到其定义或声明之前具有原型的函数,Perl 无法检查该调用是否符合该原型。您需要为有问题的子例程添加一个早期原型声明,或将子例程定义移到调用之前以获得适当的原型检查。或者,如果您确定正确调用了该函数,则可以在名称前加上一个和号以避免警告。请参阅 perlsub

%s 参数不是 HASH 或 ARRAY 元素

(F)exists() 的参数必须是哈希或数组元素,例如

$foo{$bar}
$ref->{"susie"}[12]
%s 参数不是 HASH 或 ARRAY 元素或切片

(F)delete() 的参数必须是哈希或数组元素,例如

$foo{$bar}
$ref->{"susie"}[12]

或哈希或数组切片,例如

@foo[$bar, $baz, $xyzzy]
@{$ref->[12]}{"susie", "queue"}
%s 参数不是子例程名称

(F)exists() 的参数,对于 exists &sub,必须是子例程名称,而不是子例程调用。exists &sub() 将生成此错误。

%s 包属性可能与未来的保留字冲突:%s

(W 保留)使用了具有包特定处理程序的小写属性名称。该名称将来可能对 Perl 本身有意义,即使它现在还没有。也许您应该使用混合大小写的属性名称。请参阅 attributes

(在清理中)%s

(W 杂项)此前缀通常表示 DESTROY() 方法引发了指示的异常。由于析构函数通常在执行期间的任意点由系统调用,并且通常会被调用很多次,因此对于任何数量的故障(否则会导致重复相同的错误消息),仅发出一次警告。

使用 G_KEEPERR 标志分派的失败用户回调也可能导致此警告。请参阅 perlcall 中的“G_KEEPERR”

<> 应为引号

(F) 您编写了 require <file>,而您应编写 require 'file'

尝试加入自身

(F) 您尝试从自身内部加入一个线程,这是一项不可能的任务。您可能加入了错误的线程,或者您可能需要将 join() 移至其他一些线程。

错误的已评估替换模式

(F) 您已使用 /e 开关评估替换的替换,但 perl 在要评估的代码中发现了语法错误,很可能是意外的右大括号'}'。

忽略了错误的 realloc()

(S) 一个内部例程对最初从未 malloc() 过的事物调用了 realloc()。强制执行,但可以通过将环境变量 PERL_BADFREE 设置为 1 来禁用。

在条件中发现了裸字

(W 裸字) 编译器在预期条件的地方发现了裸字,这通常表示 || 或 && 被解析为前一个构造的最后一个参数的一部分,例如

open FOO || die;

它还可能表示被解释为裸字的拼写错误常量

use constant TYPO => 1;
if (TYOP) { print "foo" }

strict 严格模式可用于避免此类错误。

二进制数 > 0b11111111111111111111111111111111 不可移植

(W 可移植) 您指定的二进制数大于 2**32-1 (4294967295),因此在系统之间不可移植。有关可移植性问题,请参阅 perlport

位向量大小 > 32 不可移植

(W 可移植) 使用大于 32 的位向量大小不可移植。

prime_env_iter 中的缓冲区溢出:%s

(W 内部) VMS 特有的警告。当 Perl 准备遍历 %ENV 时,它遇到了一个太长的逻辑名称或符号定义,因此将其截断为显示的字符串。

无法检查脚本 "%s" 的文件系统

(P) 出于某种原因,您无法检查脚本的文件系统是否为 nosuid。

无法为 %25s 中的非标量声明类

(S) 目前,只有标量变量才能在“my”或“our”声明中用特定类限定符声明。未来可能为其他类型的变量扩展语义。

无法在 %25s 中声明 %25s

(F) 只有标量、数组和哈希变量才能声明为“my”或“our”变量。它们必须具有普通标识符作为名称。

无法忽略信号 CHLD,强制为默认值

(W 信号) Perl 已检测到它在禁用 SIGCHLD 信号(有时称为 SIGCLD)的情况下运行。由于禁用此信号会干扰正确确定子进程的退出状态,因此 Perl 已将信号重置为其默认值。这种情况通常表明 Perl 可能正在运行的父程序(例如 cron)非常粗心。

无法修改非左值子例程调用

(F) 应将旨在在左值上下文中使用的子例程声明为这种类型,请参阅 "perlsub 中的左值子例程"

无法读取 CRTL 环境

(S) VMS 特有的警告。Perl 尝试从 CRTL 的内部环境数组中读取 %ENV 的元素,并发现该数组丢失。您需要找出 CRTL 错放其环境的位置,或定义 PERL_ENV_TABLES(请参阅 perlvms),以便不搜索环境。

无法删除 %25s:%25s,跳过文件

(S) 您请求了原位编辑,而没有创建备份文件。Perl 无法删除原始文件以用修改后的文件替换它。文件未修改。

无法从左值子例程返回 %25s

(F) Perl 检测到尝试从用作左值的子例程返回非法左值(例如临时值或只读值)。不允许这样做。

无法弱化非引用

(F) 您尝试减弱一个不是引用的内容。只有引用可以被减弱。

字符类 [:%s:] 未知

(F) 字符类 [: :] 语法中的类未知。请参阅 perlre

字符类语法 [%s] 属于字符类内部

(W 不安全) 字符类构造 [: :], [= =] 和 [. .] 位于字符类内部,[] 是构造的一部分,例如:/[012[:alpha:]345]/. 请注意,[= =] 和 [. .] 目前尚未实现;它们只是未来扩展的占位符。

常量不是 %s 引用

(F) 常量值(可能使用 use constant pragma 声明)正在被取消引用,但它相当于错误类型的引用。消息指示预期的引用类型。这通常表示取消引用常量值时的语法错误。请参阅 "perlsub 中的“常量函数”constant

constant(%s): %s

(F) 解析器在尝试定义重载常量或尝试查找 \N{...} 转义中指定的字符名称时发现不一致。您可能忘记加载相应的 overloadcharnames pragma?请参阅 charnamesoverload

CORE::%s 不是关键字

(F) CORE:: 命名空间专用于 Perl 关键字。

defined(@array) 已弃用

(D) defined() 通常对数组没有用,因为它检查未定义的标量值。如果您想查看数组是否为空,只需使用 if (@array) { # not empty },例如。

defined(%hash) 已弃用

(D) defined() 通常对哈希没有用,因为它检查未定义的标量值。如果您想查看哈希是否为空,只需使用 if (%hash) { # not empty },例如。

未生成有效标头

请参阅服务器错误。

(您是不是想输入“local”而不是“our”?)

(W misc) 请记住,“our”不会对已声明的全局变量进行本地化。您已在相同的词法范围内再次声明了该变量,这似乎是多余的。

文档不包含任何数据

请参阅服务器错误。

输入有效的 %s 失败

(F) 在 use filetest 编译指示下,切换实际 UID 或有效 UID 或 GID 失败。

正则表达式中错误的 [] 范围“%s”

(W regexp) 字符类范围必须以一个文本字符开头和结尾,而不是另一个字符类,如 \d[:alpha:]。您错误的范围中的“-”被解释为文本“-”。考虑引用“-”,即“\-”。请参阅 perlre

文件句柄 %s 仅打开用于输出

(W io) 您尝试从仅打开用于写入的文件句柄中读取。如果您打算将其作为读/写文件句柄,则需要使用“+<”或“+>”或“+>>”而不是“<”或不带任何内容来打开它。如果您打算仅从文件中读取,请使用“<”。请参阅 perlfunc 中的“open”

在已关闭的文件句柄 %s 上进行 flock()

(W closed) 您尝试进行 flock() 的文件句柄在一段时间前已关闭。检查您的逻辑流。flock() 在文件句柄上运行。您是否尝试使用相同名称对目录句柄调用 flock()?

全局符号“%s”需要显式包名称

(F) 您已声明“use strict vars”,这表示所有变量都必须是词法作用域(使用“my”)、使用“our”预先声明或明确限定以说明全局变量所在的包(使用“::”)。

十六进制数 > 0xffffffff 不可移植

(W portable) 您指定的十六进制数大于 2**32-1 (4294967295),因此在系统之间不可移植。有关可移植性问题,请参阅 perlport

格式错误的 CRTL environ 值“%s”

(W internal) VMS 特有的警告。Perl 尝试读取 CRTL 的内部 environ 数组,并遇到不带用于分隔键和值的 = 分隔符的元素。该元素被忽略。

prime_env_iter 中格式错误的消息:|%s|

(W internal) VMS 特有的警告。Perl 在准备迭代 %ENV 时尝试读取逻辑名称或 CLI 符号定义,并且没有看到键和值之间的预期分隔符,因此该行被忽略。

非法二进制数字 %s

(F) 您在二进制数字中使用了 0 或 1 以外的数字。

非法二进制数字 %s 已忽略

(W 数字) 您可能尝试在二进制数字中使用 0 或 1 以外的数字。二进制数字的解释在有问题的数字之前停止。

vec 中的位数非法

(F) vec() 中的位数(第三个参数)必须是 1 到 32(或 64,如果您的平台支持)的 2 的幂。

%s 数字中整数溢出

(W 溢出) 您指定为文字或作为 hex() 或 oct() 的参数的十六进制、八进制或二进制数字对于您的架构来说太大,并且已转换为浮点数。在 32 位架构上,可以表示而不会溢出的最大的十六进制、八进制或二进制数字分别为 0xFFFFFFFF、037777777777 或 0b11111111111111111111111111111111。请注意,Perl 会在内部将所有数字透明地提升为浮点表示——在后续操作中可能会损失精度。

无效的 %s 属性:%s

Perl 或用户提供的处理程序无法识别子例程或变量的指示属性。请参阅 属性

无效的 %s 属性:%s

Perl 或用户提供的处理程序无法识别子例程或变量的指示属性。请参阅 属性

regexp 中的 [] 范围 "%s" 无效

现在明确显示有问题的范围。

属性列表中分隔符字符 %s 无效

(F) 在属性列表的元素之间看到了冒号或空格以外的内容。如果前一个属性有带括号的参数列表,则该列表可能结束得太早。请参阅 属性

子例程属性列表中分隔符字符 %s 无效

(F) 在子例程属性列表的元素之间看到了冒号或空格以外的内容。如果前一个属性有带括号的参数列表,则该列表可能结束得太早。

离开有效 %s 失败

(F) 在 use filetest 编译指示下,切换实际 UID 或有效 UID 或 GID 失败。

Lvalue 子返回 %s 尚未实现

(F) 由于当前实现的限制,数组和哈希值无法在 lvalue 上下文中使用的子例程中返回。请参阅 "perlsub 中的“Lvalue 子例程”

方法 %s 不允许

请参阅服务器错误。

缺少 %sbrace%s 在 \N{}

(F) 双引号上下文中的字符名称文字 \N{charname} 语法错误。

管道打开中缺少命令

(W pipe) 您使用了 open(FH, "| command")open(FH, "command |") 构造,但命令缺失或为空。

"my sub" 中缺少名称

(F) 词法作用域子例程的保留语法要求它们具有一个名称,以便可以找到它们。

未为 -%c 指定 %s

(F) 指示的命令行开关需要一个强制参数,但您尚未指定一个。

"our" 中变量 %s 不允许使用包名称

(F) "our" 声明中不允许使用完全限定的变量名称,因为在现有语义下这没有多大意义。此类语法保留用于未来的扩展。

-%c 后不允许有空格

(F) 指示的命令行开关的参数必须紧跟在开关之后,中间没有空格。

没有 UTC 偏移信息;假设本地时间为 UTC

(S) VMS 特有的警告。Perl 无法找到本地时区偏移,因此它假设本地系统时间等同于 UTC。如果不是,请定义逻辑名称 SYS$TIMEZONE_DIFFERENTIAL 以转换为将 UTC 转换为本地时间所需的秒数。

八进制数 > 037777777777 不可移植

(W portable) 您指定的八进制数大于 2**32-1 (4294967295),因此在系统之间不可移植。有关可移植性问题,请参阅 perlport

另请参阅 perlport 以了解如何编写可移植代码。

panic: del_backref

(P) 在尝试重置弱引用时,内部一致性检查失败。

panic: kid popen errno read

(F) 分叉的子进程返回了一个关于其 errno 的不可理解的消息。

panic: magic_killbackrefs

(P) 在尝试重置对对象的全部弱引用时,内部一致性检查失败。

缺少围绕 "%s" 列表的括号

(W 括号) 您说过类似于

my $foo, $bar = @_;

而您的意思是

my ($foo, $bar) = @_;

请记住,“my”、“our”和“local”比逗号绑定得更紧密。

字符串中 %s 可能存在意外插值

(W 模糊) 过去,Perl 会尝试猜测您是想插值一个数组还是一个字面量 @。它不再这样做;现在数组始终插值到字符串中。这意味着如果您尝试类似于

print "[email protected]";

并且数组 @example 不存在,Perl 将打印 fred.com,这可能不是您想要的。要在字符串中获得一个字面量 @ 符号,请在其前加上反斜杠,就像您获得一个字面量 $ 符号一样。

可能的 Y2K 错误:%s

(W y2k) 您正在将数字 19 与另一个数字连接起来,这可能是一个潜在的 2000 年问题。

pragma “attrs” 已弃用,请改用 “sub NAME : ATTRS”

(W 已弃用) 您已经写了类似于

sub doit
{
    use attrs qw(locked);
}

您应该改用新的声明语法。

sub doit : locked
{
    ...

use attrs pragma 现已过时,仅为向后兼容性提供。请参阅 perlsub 中的“子例程属性”

脚本头过早结束

请参阅服务器错误。

pack 中的重复计数溢出

(F) 您不能指定一个重复计数,它会大到溢出您的有符号整数。请参阅 perlfunc 中的“pack”

unpack 中的重复计数溢出

(F) 您不能指定一个重复计数,它会大到溢出您的有符号整数。请参阅 perlfunc 中的“unpack”

忽略了已释放内存的 realloc()

(S) 一个内部例程在已释放的内容上调用了 realloc()。

引用已弱

(W misc) 您已尝试减弱一个已弱的引用。这样做没有任何效果。

setpgrp 无法接受参数

(F) 您的系统具有来自 BSD 4.2 的 setpgrp(),它不接受参数,这与 POSIX setpgid() 不同,后者接受进程 ID 和进程组 ID。

在零长度表达式上出现奇怪的 *+?{}

(W regexp) 您在没有意义的地方应用了正则表达式量词,例如在零宽断言上。尝试将量词放在断言内部。例如,匹配“abc”的方式是它后跟三个重复的“xyz”,即 /abc(?=(?:xyz){3})/,而不是 /abc(?=xyz){3}/

切换有效 %s 未实现

(F) 在 use filetest 实用程序下,我们无法切换实际和有效的 uid 或 gid。

此 Perl 无法重置 CRTL 环境元素 (%s)
此 Perl 无法设置 CRTL 环境元素 (%s=%s)

(W internal) VMS 特有的警告。您尝试更改或删除 CRTL 的内部环境数组的一个元素,但您的 Perl 副本不是使用包含 setenv() 函数的 CRTL 构建的。您需要使用包含 setenv() 函数的 CRTL 重新构建 Perl,或重新定义 PERL_ENV_TABLES(请参阅 perlvms),以便环境数组不是导致警告的 %ENV 更改的目标。

运行 %s 块太迟

(W void) 在运行时正确定义了 CHECK 或 INIT 块,而此时运行它们的机会已经过去。也许您在应该使用 use 时使用 requiredo 加载文件。或者,您应该将 requiredo 放在 BEGIN 块中。

未知的 open() 模式 '%s'

(F) 三个参数 open() 的第二个参数不在有效模式列表中:<>>>+<+>+>>-||-

未知进程 %x 向 prime_env_iter 发送消息:%s

(P) VMS 特有的错误。Perl 在迭代 %ENV 之前读取其值,而其他人将一条消息粘贴到 Perl 预期的数据流中。有人非常困惑,或者可能试图出于恶意目的破坏 Perl 对 %ENV 的填充。

无法识别的转义字符 \\%c 传递

(W misc) 您使用了 Perl 无法识别的反斜杠字符组合。字符被理解为字面意思。

属性列表中未终止的属性参数

(F) 词法分析器在解析属性列表时看到了一个左括号字符,但未找到匹配的右括号字符。您可能需要添加(或删除)一个反斜杠字符来平衡括号。请参阅 属性

未终止的属性列表

(F) 词法分析器在属性开头找到了一个非简单标识符,它不是分号或块的开头。您可能过早地终止了前一个属性的参数列表。请参阅 属性

子例程属性列表中未终止的属性参数

(F) 词法分析器在解析子例程属性列表时看到了一个左括号字符,但未找到匹配的右括号字符。您可能需要添加(或删除)一个反斜杠字符来平衡括号。

未终止的子例程属性列表

(F) 词法分析器在子例程属性开头找到了一个非简单标识符,它不是分号或块的开头。您可能过早地终止了前一个属性的参数列表。

CLI 符号 "%s" 的值太长

(W misc) VMS 特有的警告。Perl 尝试从 CLI 符号表中读取 %ENV 元素的值,并发现结果字符串长于 1024 个字符。返回值已被截断为 1024 个字符。

版本号必须是常数

(P) 尝试将 use Module n.n LIST 语句转换为等效的 BEGIN 块时,发现版本号存在内部不一致。

新测试

lib/attrs

sub : attrs 与旧版 use attrs 的兼容性测试。

lib/env

新环境标量功能的测试(例如,use Env qw($BAR);)。

lib/env-array

新环境数组功能的测试(例如,use Env qw(@PATH);)。

lib/io_const

IO 常量(SEEK_*, _IO*)。

lib/io_dir

与目录相关的 IO 方法(new、read、close、rewind、tied delete)。

lib/io_multihomed

具有多宿主的 INET 套接字。

lib/io_poll

IO poll()。

lib/io_unix

UNIX 套接字。

op/attrs

my ($x,@y,%z) : attrs 和 <sub : attrs> 的回归测试。

op/filetest

文件测试运算符。

op/lex_assign

验证访问垫对象(词法和临时对象)的操作。

op/exists_sub

验证 exists &sub 操作。

不兼容的更改

Perl 源代码不兼容

请注意,任何已添加的新警告或已增强的旧警告都被视为不兼容的更改。

由于所有新警告都必须通过 -w 开关或 warnings pragma 显式请求,因此最终由程序员负责确保明智地启用警告。

CHECK 是一个新关键字

所有名为 CHECK 的子例程定义现在都是特殊的。有关更多信息,请参见 /"Support for CHECK blocks"

对 undef 的列表切片的处理已更改

完全由未定义值组成的列表切片的行为存在潜在的不兼容性。请参见 "列表切片行为更加一致"

$English::PERL_VERSION 的格式不同

英语模块现在将 $PERL_VERSION 设置为 $^V(一个字符串值),而不是 $](一个数字值)。这是一种潜在的不兼容性。如果您受到此影响,请通过 perlbug 向我们发送报告。

有关此更改的原因,请参见"改进的 Perl 版本编号系统"

形式为 1.2.3 的文字解析不同

以前,带有不止一个点的数字文字被解释为一个浮点数,连接一个或多个数字。此类“数字”现在被解析为由指定序数组成的字符串。

例如,print 97.98.99 在早期版本中用于输出 97.9899,但现在输出 abc

请参见"表示为序数向量的字符串支持"

可能更改的伪随机数生成器

依赖于生成一组特定伪随机数的 Perl 程序现在可能由于对 rand() 内置函数的改进而产生不同的输出。您可以使用 sh Configure -Drandfunc=rand 来获取旧的行为。

请参见"更好的伪随机数生成器"

散列键的散列函数已更改

即使 Perl 散列不保留顺序,在散列内容上进行迭代时遇到的明显随机顺序实际上是由所使用的散列算法决定的。算法的改进可能会产生与以前版本不同的随机顺序,尤其是在对散列进行迭代时。

有关更多信息,请参见"散列的更佳最坏情况行为"

undef 在只读值上失败

对只读值(例如 $1)使用 undef 运算符与将 undef 赋值给只读值具有相同的效果——它会引发异常。

管道和套接字句柄上可能设置了关闭执行位

管道和套接字句柄现在也受特殊变量 $^F 确定的关闭执行行为的影响。

请参见"更一致的关闭执行行为"

编写 "$$1" 表示 "${$}1" 不受支持

Perl 5.004 不赞成在插值字符串中将 $$1 等解释为 $$ . "1",但仍然允许这样做。

在 Perl 5.6.0 及更高版本中,"$$1" 始终表示 "${$1}"

delete()、each()、values() 和 \(%h)

操作别名而不是副本

在一个列表上下文中,delete()、each()、values() 和哈希(例如 \(%h))返回哈希中的实际值,而不是副本(正如它们在早期版本中所做的那样)。使用这些构造的典型习惯用法是复制返回的值,但当创建对返回值的引用时,这可能会产生重大差异。在对哈希进行迭代时,哈希中的键仍作为副本返回。

另请参阅 "delete()、each()、values() 和哈希迭代更快"

vec(EXPR,OFFSET,BITS) 强制执行 2 的 BITS 次幂

如果 BITS 参数不是有效的 2 的整数次幂,则 vec() 会生成运行时错误。

一些诊断输出的文本已更改

诊断中对内部 Perl 操作的大多数引用都已更改为更具描述性。对于可能错误地依赖诊断的确切文本以正常运行的程序来说,这可能是一个问题。

已删除 %@

已删除过去用于累积“后台”错误(例如在 DESTROY() 中发生的错误)的未记录特殊变量 %@,因为它可能会导致内存泄漏。

带括号的 not() 表现得像一个列表运算符

not 运算符现在属于“如果它看起来像一个函数,它就表现得像一个函数”规则。

因此,带括号的形式可与 grepmap 一起使用。以下构造以前是语法错误,但现在按预期工作

grep not($_), @things;

另一方面,将 not 与字面列表切片一起使用可能不起作用。以下以前允许的构造

print not (1,2,3)[0];

现在需要用额外的括号编写

print not((1,2,3)[0]);

not 后面不跟着括号时,行为不受影响。

裸字原型 (*) 的语义已更改

裸字原型 * 的语义已更改。Perl 5.005 始终将简单的标量参数强制转换为类型全局,这在子例程必须区分简单标量和类型全局的情况下没有用。新行为是不将裸字参数强制转换为类型全局。该值将始终显示为简单标量或对类型全局的引用。

参见 "更多功能的裸字原型 (*)"

在 64 位平台上,位运算符的语义可能已更改

如果您的平台是原生 64 位,或者 Perl 已配置为使用 64 位整数,即 $Config{ivsize} 为 8,则位运算符 (& | ^ ~ << >>) 的行为中可能存在潜在的不兼容性。这些运算符过去严格操作整数的低 32 位,但现在操作整个原生整数宽度。特别是,请注意,在具有不同 $Config{ivsize} 的平台上,一元 ~ 将产生不同的结果。为了便于移植,务必屏蔽掉一元 ~ 结果中的多余位,例如 ~$x & 0xffffffff

请参阅 “位运算符支持完整的原生整数宽度”

更多内置函数污染其结果

“改进的安全功能” 中所述,Perl 程序中可能存在更多污染源。

要避免这些新的污染行为,您可以使用 Configure 选项 -Accflags=-DINCOMPLETE_TAINTS 构建 Perl。请注意,由此产生的 perl 二进制文件可能不安全。

C 源不兼容性

PERL_POLLUTE

5.005 版通过为扩展源兼容性提供预处理器宏来保留旧的全局符号名称。从 5.6.0 版开始,这些预处理器定义默认不可用。您需要使用 -DPERL_POLLUTE 显式编译 perl 以获取这些定义。对于仍使用旧符号的扩展,可以通过 MakeMaker 指定此选项

perl Makefile.PL POLLUTE=1
PERL_IMPLICIT_CONTEXT

此新的构建选项为所有 API 函数提供了一组宏,以便将隐式解释器/线程上下文参数传递给每个 API 函数。因此,诸如 sv_setsv(foo,bar) 之类的内容等同于宏调用,实际上转换为诸如 Perl_sv_setsv(my_perl,foo,bar) 之类的内容。虽然通常预计不会有任何重大的源兼容性问题,但需要考虑宏和实际函数调用之间的差异。

这意味着,如果您的扩展尝试使用指向任何 Perl API 函数的指针,则会因此 出现 源兼容性问题。

请注意,上述问题与 Perl 的默认构建无关,其接口继续与以前版本匹配(但受此处描述的其他选项约束)。

请参阅 perlguts 中的“背景和 PERL_IMPLICIT_CONTEXT”,了解使用此选项构建 Perl 的影响的详细信息。

NOTE: PERL_IMPLICIT_CONTEXT is automatically enabled whenever Perl is built
with one of -Dusethreads, -Dusemultiplicity, or both.  It is not
intended to be enabled by users at this time.
PERL_POLLUTE_MALLOC

在 5.005 及更早版本中启用 Perl 的 malloc 会导致系统 malloc 系列函数的命名空间被 Perl 版本篡夺,因为它们默认使用相同的名称。除了在不允许干净替换这些函数的平台上导致问题之外,这也意味着在使用 Perl 的 malloc 的程序中无法调用系统版本。以前版本的 Perl 允许使用 HIDEMYMALLOC 和 EMBEDMYMALLOC 预处理器定义来禁止这种行为。

从 5.6.0 版本开始,Perl 的 malloc 系列函数的默认名称与系统版本不同。您需要使用 -DPERL_POLLUTE_MALLOC 明确编译 perl 才能获得较旧的行为。HIDEMYMALLOC 和 EMBEDMYMALLOC 没有任何效果,因为它们启用的行为现在是默认行为。

请注意,这些函数构成 Perl 的内存分配 API。有关该 API 的更多信息,请参见 perlguts 中的“内存分配”

兼容的 C 源代码 API 更改

PATCHLEVEL 现在是 PERL_VERSION

cpp 宏 PERL_REVISIONPERL_VERSIONPERL_SUBVERSION 现在可从 perl.h 中默认获得,并分别反映基本修订版、补丁级别和次级版本。PERL_REVISION 之前没有等效项,而 PERL_VERSIONPERL_SUBVERSION 之前可作为 PATCHLEVELSUBVERSION 获得。

新名称减少了对cpp 命名空间的污染,并反映了这些数字在惯例中代表的含义。为了兼容性,当明确包含 patchlevel.h(如之前所要求的)时,旧名称仍然受支持,因此更改不会导致源代码不兼容。

二进制不兼容性

一般来说,此版本的默认构建预计与使用 5.005 版本或其维护版本构建的扩展二进制兼容。但是,由于提示文件中使用的默认值发生更改,特定平台可能会破坏二进制兼容性。因此,请务必始终查看特定于平台的自述文件,了解任何相反的说明。

usethreads 或 usemultiplicity 构建与 5.005 中的相应构建二进制兼容。

在需要明确导出列表的平台上(包括 AIX、OS/2 和 Windows),解析器函数和运行时操作码等纯内部符号默认情况下不会导出。Perl 5.005 过去会导出所有函数,无论它们是否被视为公共 API 的一部分。

有关公共 API 函数的完整列表,请参见 perlapi

已知问题

线程测试失败

已知 lib/thr5005.t 测试的子测试 19 和 20 由于 5.005 线程实现中的基本问题而失败。这些不是新失败——Perl 5.005_0x 具有相同的错误,但没有这些测试。

EBCDIC 平台不受支持

在早期版本的 Perl 中,支持 EBCDIC 环境,如 OS390(也称为 Open Edition MVS)和 VM-ESA。由于 UTF-8(Unicode)支持所需的更改,EBCDIC 平台在 Perl 5.6.0 中不受支持。

在 64 位 HP-UX 中,lib/io_multihomed 测试可能挂起

如果已将 Perl 配置为 64 位,则 lib/io_multihomed 测试可能会在 HP-UX 中挂起。由于其他 64 位平台不会在此测试中挂起,因此 HP-UX 可疑。所有其他测试均在 64 位 HP-UX 中通过。该测试尝试创建“多宿”套接字(具有多个 IP 地址的套接字)并连接到它们。

NEXTSTEP 3.3 POSIX 测试失败

在 NEXTSTEP 3.3p2 中,操作系统库中 strftime(3) 的实现存在错误:%j 格式从零开始对一个月的日期进行编号,这虽然对程序员来说是合乎逻辑的,但会导致 lib/posix 测试的子测试 19 到 27 可能失败。

Tru64(又称 Digital UNIX,又称 DEC OSF/1)lib/sdbm 测试与 gcc 一起失败

如果使用 gcc 2.95 编译,lib/sdbm 测试将失败(转储核心)。解决方法是使用供应商 cc,它随操作系统一起提供并生成良好的代码。

UNICOS/mk CC 在 Configure 运行期间失败

在 UNICOS/mk 中,以下错误可能在 Configure 运行期间出现

Guessing which symbols your C compiler and preprocessor define...
CC-20 cc: ERROR File = try.c, Line = 3
...
  bad switch yylook 79bad switch yylook 79bad switch yylook 79bad switch yylook 79#ifdef A29K
...
4 errors detected in the compilation of "try.c".

罪魁祸首是 UNICOS/mk 的损坏 awk。幸运的是,影响相当轻微:Perl 本身不受错误的不利影响,只有 Perl 附带的 h2ph 实用程序,而现在很少需要它。

箭头运算符和数组

当箭头运算符 -> 的左参数是数组,或对数组进行操作的 scalar 运算符时,必须将操作的结果视为错误。例如

@x->[2]
scalar(@x)->[2]

在某些未来的 Perl 版本中,这些表达式将获得运行时错误。

实验性功能

如上所述,许多功能仍在试验中。这些功能的接口和实现可能会更改,在极端情况下,甚至可能会在某些未来的 Perl 版本中被移除。这些功能包括以下内容

线程
Unicode
64 位支持
左值子例程
弱引用
伪哈希数据类型
编译器套件
文件通配符的内部实现
DB 模块
正则表达式代码构造

(?{ code })(??{ code })

过时的诊断

字符类语法 [: :] 保留用于未来的扩展

(W) 在正则表达式字符类 ([]) 中,以 "[:" 开头并以 ":]" 结尾的语法保留用于未来的扩展。如果你需要在正则表达式字符类中表示这些字符序列,只需用反斜杠引用方括号:"\[:" 和 ":\]"。

prime_env_iter 中的逻辑名称 |%s| 格式不正确

(W) VMS 特有的警告。在准备对 %ENV 进行迭代时遇到一个逻辑名称,它违反了控制逻辑名称的语法规则。因为它无法正常转换,所以它被跳过,不会出现在 %ENV 中。这可能是一个良性事件,因为某些软件包可能会直接修改逻辑名称表并引入非标准名称,或者它可能表明逻辑名称表已损坏。

在字符串中,@%s 现在必须写成 \@%s

此错误的描述以前是

(Someday it will simply assume that an unbackslashed @
 interpolates an array.)

那一天已经到来,并且此致命错误已被移除。它已被非致命警告取代。有关详细信息,请参阅"数组现在总是插值到双引号字符串中"

%s 上的可能优先级问题

(W) 编译器在预期条件时找到一个裸字,这通常表明 || 或 && 已被解析为前一个构造的最后一个参数的一部分,例如

open FOO || die;
正则表达式太大

(F) 正则表达式的当前实现使用短整型作为字符串中的地址偏移量。不幸的是,这意味着如果正则表达式编译为超过 32767,它将爆炸。通常,当您想要一个如此大的正则表达式时,可以使用多条语句来实现更好的方法。请参阅perlre

使用 "$$<digit>" 来表示 "${$}<digit>" 已弃用

(D) 5.004 之前的 Perl 版本错误地解释了任何类型标记后跟 "$" 和一个数字。例如,"$$0" 被错误地理解为 "${$}0" 而不是 "${$0}"。此错误在 Perl 5.004 中(大部分)已修复。

但是,Perl 5.004 的开发者无法完全修复此错误,因为至少有两个广泛使用的模块依赖于字符串中 "$$0" 的旧含义。因此,Perl 5.004 仍然以旧(已损坏)的方式解释字符串中的 "$$<digit>";但它会生成此消息作为警告。在 Perl 5.005 中,这种特殊处理将停止。

报告错误

如果您发现您认为是错误的内容,您可以查看最近发布到 comp.lang.perl.misc 新闻组的文章。Perl 主页 https://perldotcom.perl5.cn/perl/ 上也可能有信息。

如果您认为自己有一个未报告的错误,请运行发行版中包含的perlbug程序。务必将错误精简为一个微小但足够的测试用例。您的错误报告以及perl -V的输出将被发送到 [email protected],供 Perl 移植团队分析。

另请参阅

Changes 文件,详细说明了更改的内容。

INSTALL 文件,用于说明如何构建 Perl。

README 文件,用于说明常规内容。

ArtisticCopying 文件,用于说明版权信息。

历史

由 Gurusamy Sarathy <[email protected]> 编写,并得到了 Perl Porters 的大量帮助。

将遗漏或更正内容发送至 <[email protected]>。