perl561delta - perl v5.6.1 的新增功能
本文档描述了 5.005 版本和 5.6.1 版本之间的差异。
本节包含 5.6.0 版本和 5.6.1 版本之间的更改摘要。有关此处提到的更改的更多详细信息,请参阅随 Perl 源代码分发提供的 Changes 文件。有关如何检查这些更改描述的各个补丁的在线资源的指针,请参阅 perlhack。
suidperl 不会再运行 /bin/mail,因为某些平台上的 /bin/mail 存在缓冲区溢出攻击漏洞。
请注意,suidperl 在任何最近版本的 perl 中都不会默认构建或安装。强烈建议不要使用 suidperl。如果您认为需要它,请先尝试使用 sudo 等替代方案。请参阅 http://www.courtesan.com/sudo/。
这不是一个详尽的列表。它旨在涵盖仅对用户可见的重大更改。
UNIVERSAL::isa()
已修复 UNIVERSAL::isa()
使用的缓存机制中的一个错误,该错误影响了 base.pm。该错误自 5.005 版本以来一直存在,但在这些版本中没有被 base.pm 触发。
已修复各种内存泄漏和尝试访问未初始化内存的情况。有关更多问题,请参阅下面的 "已知问题"。
在某些情况下,数值转换无法正确识别字符串值的更改。
在其他情况下,大型无符号数(大于 2**31 的数)有时会丢失其无符号性,导致算术运算产生错误结果。
大型无符号整数的整数模运算有时会返回不正确的值。
Perl 5.6.0 在某些转换中生成了“非数字”警告,而以前的版本没有。
这些问题都已得到纠正。
现在,无穷大被识别为一个数字。
在 Perl 5.6.0 中,qw(a\\b) 生成了一个包含两个反斜杠而不是一个反斜杠的字符串,这与以前版本的行为不同。已恢复旧的行为。
caller() 在某些情况下会导致核心转储。Carp 有时会受到此问题的影响。
现在,对重载值的模式匹配得到正确处理。
Perl 5.6.0 错误地解析了 m/\x{ab}/,导致出现虚假警告。此问题已得到纠正。
Perl 5.6.0 中的 RE 引擎意外地对某些类型的简单模式匹配进行了悲观优化。现在这些情况得到了更好的处理。
正则表达式调试输出(无论是通过 use re 'debug'
还是通过 -Dr
)现在看起来更好了。
多行匹配,例如 "a\nxb\n" =~ /(?!\A)x/m
,存在缺陷。该错误已修复。
在某些情况下,使用 $& 会触发核心转储。现在已避免这种情况。
当模式匹配回溯时,匹配变量 $1 等没有被取消设置,并且异常出现在 /...(?{ ... }).../
等内部。现在这些变量被正确跟踪。
在早期版本中,pos() 在 s///ge 中没有返回正确的值。现在已得到正确处理。
在某些情况下,以 "slurp" 模式打开的文件上的 readline() 在末尾可能会返回额外的 ""。此问题已得到修正。
对 perlvar 中描述的特殊变量的符号引用的自动生成(如 ${$num}
)意外地被禁用。现在它再次起作用。
词法警告现在可以正确地传播到 eval "..."
中。
use warnings qw(FATAL all)
未按预期工作。此问题已得到修正。
在某些情况下,词法警告可能会泄漏到其他作用域。现在已修复。
如果调用者未使用词法警告,warnings::enabled() 现在会正确地报告 $^W 的状态。
Perl 5.6.0 在将扩展静态构建到 perl 中时,可能会发出关于 dl_error() 重新定义的虚假警告。此问题已得到修正。
"our" 变量可能会导致虚假的 "变量将不会保持共享" 警告。现在已修复。
在两个兄弟块中声明的同名 "our" 变量会导致关于变量 "重新声明" 的虚假警告。此问题已得到修正。
内置 glob() 与旧的基于 csh 的 glob 的兼容性已通过添加 GLOB_ALPHASORT 选项得到改进。参见 File::Glob
。
File::Glob::glob() 已重命名为 File::Glob::bsd_glob(),因为该名称与内置的 glob() 冲突。为了兼容性,旧名称仍然可用,但已弃用。
在某些情况下,当 glob() 首次导致加载 File::Glob 时,生成的虚假语法错误已得到修复。
已修复一些不一致的污染传播情况(例如哈希值内部)。
已理顺 sprintf() 的污染行为。它不再污染浮点格式的结果,使其行为与字符串插值一致。
sort() 的参数没有被提供正确的 wantarray() 上下文。比较块现在在标量上下文中运行,并且要排序的参数始终被提供列表上下文。
sort() 也是完全可重入的,这意味着排序函数本身可以调用 sort()。这在以前的版本中无法可靠地工作。
#line 指令现在在它们出现在 eval "..."
的开头时可以正常工作。
(\&) 原型现在可以正常工作。
当 map() 生成的结果列表大于源列表时,它可能会变得异常缓慢。已针对常见场景改进了性能。
调试器退出代码现在反映脚本退出代码。
断点中的条件 "0"
现在被正确处理。
d
命令现在检查行号。
$.
不再被调试器破坏。
所有调试器输出现在都正确地发送到套接字(如果设置了 RemotePort)。
PERL5OPT 可以设置为多个开关组。以前,它仅限于一组选项。
列表上下文中的 chop(@list) 以相反的顺序返回被截断的字符。这已反转为正确的顺序。
Unicode 支持已经经历了大量的增量改进,但仍处于高度实验阶段。预计在 5.6.x 维护版本中不会完全支持。
substr()、join()、repeat()、reverse()、quotemeta() 和字符串连接在 Perl 5.6.0 中都错误地处理了 Unicode 字符串。此问题已得到修复。
对 tr///CU
和 tr///UC
等的支持已被移除,因为我们意识到该接口存在问题。有关类似功能,请参见 "perlfunc 中的 pack"。
Unicode 字符数据库已更新至 3.0.1 版本,其中包含截至 2000 年 8 月 30 日公开发布的补充内容。
已添加 Unicode 字符类 \p{Blank} 和 \p{SpacePerl}。"Blank" 类似于 C 中的 isblank(),即它仅包含“水平空白”(空格字符是,换行符不是),而 "SpacePerl" 是 \s
的 Unicode 等效项(\p{Space} 不是,因为它包括垂直制表符,而 \s
不包括)。
如果您正在尝试 Perl 中的 Unicode 支持,开发版本的 Perl 可能提供更多功能。特别是,I/O 层现在在开发轨道中可用,但在维护轨道中不可用,这主要是为了解决向后兼容性问题。Unicode 支持在开发轨道中也每天都在快速发展——维护轨道只反映了这些变化中最保守的部分。
对 64 位平台的支持已得到改进,但仍处于实验阶段。不同平台之间的支持程度差异很大。
B 编译器及其各种后端已经进行了许多增量改进,但它们仍然处于高度实验阶段。不建议在生产环境中使用。
perlcc 工具已重写,因此用户界面更类似于 C 编译器。
perlbc 工具已被移除。请改用 perlcc -B
。
已经进行了各种错误修复以更好地支持左值子程序。但是,该功能仍然处于实验阶段。
如果服务名称未知,IO::Socket::INET 无法打开指定的端口。现在它会正确地使用提供的端口号。
File::Find 现在在跟踪符号链接时会正确地执行 chdir()。
xsubpp 现在可以容忍嵌入的 POD 部分。
no Module;
即使 Module 没有 unimport() 方法,no Module;
也不会产生错误。这与 use
相对于 import
的行为一致。
添加了许多测试。
untie() 现在会调用 UNTIE() 钩子(如果存在)。有关详细信息,请参阅 perltie。
-DT
命令行开关输出大量的标记信息。请参阅 perlrun。
数组现在始终在双引号字符串中进行插值。以前,如果未使用或声明数组 @bar
,则 "[email protected]"
会在编译时导致致命错误。这种过渡行为旨在帮助迁移 perl4 代码,现在被认为不再有用。请参阅 "数组现在始终插值到双引号字符串中"。
keys()、each()、pop()、push()、shift()、splice() 和 unshift() 现在都可以被重写。
my __PACKAGE__ $obj
现在按预期工作。
在某些系统(包括 IRIX 和 Solaris)上,系统 malloc 明显更好。虽然默认值没有改变以保持与早期版本的二进制兼容性,但您最好使用 Configure -Uusemymalloc ...
构建 perl,如 INSTALL 文件中所述。
Configure
已在多个方面得到增强
最大限度地减少对临时文件的使用。
默认情况下,不会将 perl 与它未使用的库链接,例如各种 dbm 库。SunOS 4.x 提示保留该平台上的行为。
由于过时,对 pdp11 风格的内存模型的支持已被移除。
在支持符号链接的系统上,支持在源代码树之外构建。这可以通过运行以下命令来完成
sh /path/to/source/Configure -Dmksymlinks ...
make all test install
在 Perl 源代码目录以外的目录中。请参阅 INSTALL。
Configure -S
可以非交互式运行。
已添加 README.aix、README.solaris 和 README.macos。README.posix-bc 已重命名为 README.bs2000。这些分别安装为 perlaix、perlsolaris、perlmacos 和 perlbs2000。
以下 pod 文档是全新的
perlclib Internal replacements for standard C library functions
perldebtut Perl debugging tutorial
perlebcdic Considerations for running Perl on EBCDIC platforms
perlnewmod Perl modules: preparing a new module for distribution
perlrequick Perl regular expressions quick start
perlretut Perl regular expressions tutorial
perlutil utilities packaged with the Perl distribution
INSTALL 文件已扩展以涵盖各种问题,例如 64 位支持。
已在源代码分发中添加了更长的贡献者列表。请参阅 AUTHORS
文件。
对包含的文档和常见问题解答进行了大量其他更改。
已添加以下模块。
遍历 Perl 语法树,打印有关操作的简洁信息。请参阅 B::Concise。
安全地返回临时文件的名称和句柄。请参阅 File::Temp。
将 Pod 数据转换为格式化的 LaTeX。请参阅 Pod::LaTeX。
将 POD 数据转换为格式化的删除线文本。请参阅 Pod::Text::Overstrike。
以下模块已升级。
现在包含 CGI v2.752。
现在包含 CPAN v1.59_54。
已添加各种错误修复。
DB_File v1.75 支持更新的 Berkeley DB 版本,以及其他改进。
Devel::Peek 已增强以支持转储内存统计信息,当 perl 使用包含的 malloc() 构建时。
File::Find 现在支持对文件进行预处理和后处理,以便对它们进行排序() 等。
包含 Getopt::Long v2.25。
包含各种错误修复。
IPC::Open3 允许使用数字文件描述符。
fmod() 函数支持模运算。还包含各种错误修复。
Math::Complex 更好地处理 inf、NaN 等。
ping() 在奇数个数据字节或回显服务未运行时可能会失败。此问题已得到修复。
已修复内存泄漏。
包含 Pod::Parser 套件的 1.13 版本。
Pod::Text 和相关模块已升级到 podlators 套件 v2.08 中的版本。
在 dosish 平台上,由于缺乏对带“洞”文件的支持,一些键丢失了。已添加解决此问题的变通方法。
包含各种错误修复。
现在支持 Tie::RefHash::Nestable 以自动绑定 hashref 值。
包含各种错误修复。
现在提供以下新端口。
Perl 现在可以在 Amdahl UTS 下构建。
Perl 也已验证可以在 Amiga OS 下构建。
对 EPOC 的支持已得到很大改进。请参阅 README.epoc。
使用 -Duseithreads 或 -Duse5005threads 构建 perl 现在可以在 HP-UX 10.20 下工作(以前它只能在 10.30 或更高版本下工作)。您需要安装线程库包。请参阅 README.hpux。
长双精度现在应该可以在 Linux 下工作。
Mac OS Classic 现在在主流源代码包中受支持。请参阅 README.macos。
对 MPE/iX 的支持已更新。请参阅 README.mpeix。
对 OS/2 的支持已得到改进。请参阅 os2/Changes
和 README.os2。
z/OS(以前称为 OS/390)上的动态加载已得到改进。请参阅 README.os390。
对 VMS 的支持已取得许多增量改进,包括对反引号和 system() 等运算符的更好支持,以及更好的 %ENV 处理。请参阅 README.vms
和 perlvms.
对 Stratus VOS 的支持已得到改进。请参阅 vos/Changes
和 README.vos。
Windows 支持已得到改进。
fork() 模拟在各个方面都得到了改进,但仍然处于实验阶段。有关已知错误和注意事项,请参见 perlfork。
%SIG 已在 USE_ITHREADS 下启用,但在所有配置下其使用均不受支持。
Borland C++ v5.5 现在是支持的编译器,可以构建 Perl。但是,生成的二进制文件与其他支持的编译器(GCC 和 Visual C++)生成的二进制文件不兼容。
通过 waitpid($pid, &POSIX::WNOHANG)
支持对子进程(或伪进程)的非阻塞等待。
已修复 accept() 中的内存泄漏。
wait()、waitpid() 和反引号现在在 Windows 9x 下返回正确的退出状态。
尾随的新的 %ENV 条目未传播到子进程。现在已修复。
%ENV 中的当前目录条目现在已正确传播到子进程。
使用 open(F, ">&MYSOCK") 复制套接字句柄现在在 Windows 9x 下有效。
Makefile 现在提供了一个开关,用于批量启用 ActiveState ActivePerl(一个流行的二进制发行版)中启用的所有功能。
Win32::GetCwd() 在驱动器根目录时正确返回 C:\ 而不是 C:。chdir() 和 Cwd::cwd() 中的其他错误也已修复。
fork() 在用完伪进程句柄时正确返回 undef 并设置 EAGAIN。
ExtUtils::MakeMaker 现在使用 $ENV{LIB} 搜索库。
当 perl 构建为支持 fork() 时,UNC 路径处理得到改进。
已修复套接字处理中的句柄泄漏。
send() 可在伪进程中使用。
除非另有说明,否则本文档的其余部分涵盖 5.005 和 5.6.0 版本之间的更改。
Perl 5.6.0 引入了在不同线程中并发运行多个解释器的支持。结合 perl_clone() API 调用,该调用可用于选择性地复制任何给定解释器的状态,可以将一段代码在一个解释器中编译一次,克隆该解释器一次或多次,并在不同的线程中运行所有生成的解释器。
在 Windows 平台上,此功能用于在解释器级别模拟 fork()。有关详细信息,请参见 perlfork。
此功能仍在不断发展。它最终将用于选择性地克隆一个子例程以及从该子例程可达到的数据,并在一个单独的解释器中运行克隆的子例程。由于解释器之间没有共享数据,因此几乎不需要锁定(除非显式共享符号表的一部分)。这显然旨在成为现有线程支持的易于使用的替代方案。
可以使用 -Dusethreads Configure 选项启用对克隆解释器和解释器并发的支持(有关如何在 Windows 上启用它,请参见 win32/Makefile)。生成的 perl 可执行文件在功能上与使用 -Dmultiplicity 构建的 perl 可执行文件相同,但 perl_clone() API 调用仅在前者中可用。
-Dusethreads 默认情况下启用 cpp 宏 USE_ITHREADS,这反过来又启用了 Perl 源代码更改,这些更改提供了操作树与其操作的数据之间的明确分离。前者是不可变的,因此可以在解释器及其所有克隆之间共享,而后者被认为是每个解释器的本地,因此在每个克隆中都会被复制。
请注意,如果您希望在不同的线程中并发运行多个独立解释器,则使用 -Dusemultiplicity Configure 选项构建 Perl 就足够了。-Dusethreads 仅提供 perl_clone() API 调用的附加功能以及其他支持,用于并发运行克隆的解释器。
NOTE: This is an experimental feature. Implementation details are
subject to change.
现在可以使用 use warnings
编译指示来更细粒度地控制 Perl 发出的警告。有关此功能的详细文档,请参阅 warnings 和 perllexwarn。
Perl 现在使用 UTF-8 作为其字符字符串的内部表示。utf8
和 bytes
编译指示用于控制当前词法作用域中的此支持。有关更多信息,请参阅 perlunicode、utf8 和 bytes。
此功能预计会快速发展,以支持某种形式的 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" 声明引入一个值,该值可以最好地理解为对声明变量时当前包中的全局变量的词法作用域符号别名。这主要用作 vars
编译指示的替代方案,但也提供了为这些变量引入类型和其他属性的机会。请参阅 "our" in perlfunc。
现在将 v1.2.3.4
形式的字面量解析为由具有指定序数的字符组成的字符串。这是一种替代的、更易读的方式来构造(可能是 Unicode)字符串,而不是插值字符,例如 "\x{1}\x{2}\x{3}\x{4}"
。如果存在两个以上的序数,则可以省略前导 v
,因此 1.2.3
解析方式与 v1.2.3
相同。
以这种形式编写的字符串也用于表示版本“号”。使用任何常用的字符串比较运算符 eq
、ne
、lt
、gt
等,或使用 |
、&
等对它们执行按位字符串运算,可以轻松比较这些版本“号”(实际上只是普通字符串)。
结合新的 $^V
魔术变量(包含 Perl 版本作为字符串),这些字面量可以用作一种易读的方式来检查您是否正在运行特定版本的 Perl。
# this will parse in older versions of Perl also
if ($^V and $^V gt v5.6.0) {
# new features supported
}
require
和 use
也有一些特殊魔术来支持这些字面量。它们将被解释为版本而不是模块名称。
require v5.6.0; # croak if $^V lt v5.6.0
use v5.6.0; # same, but croaks at compile-time
或者,如果存在多个点,则可以省略 v
。
require 5.6.0;
use 5.6.0;
此外,sprintf
和 printf
支持 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
有关更多信息,请参阅 "Scalar value constructors" in perldata。
从 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
编译指示进行声明。现在可以使用声明语法来完成,如下所示
sub mymethod : locked method;
...
sub mymethod : locked method {
...
}
sub othermethod :locked :method;
...
sub othermethod :locked :method {
...
}
(注意,只有第一个 :
是必需的,:
周围的空格是可选的。)
AutoSplit.pm 和 SelfLoader.pm 已更新,以保留它们提供的存根中的属性。请参阅 属性。
类似于 $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" in perlfunc。
任何具有 64 位整数的平台都可以
(1) natively as longs or ints
(2) via special compiler flags
(3) using long long or int64_t
能够使用“quads”(64 位整数)如下
代码中的常量(十进制、十六进制、八进制、二进制)
`oct()` 和 `hex()` 的参数
`print()`、`printf()` 和 `sprintf()` 的参数(标志前缀 ll、L、q)
按此打印
`pack()` 和 `unpack()` 的“q”和“Q”格式
在基本算术运算中:+ - * / %(注意:接近整数值限制的操作可能会产生意外结果)
在位运算中:& | ^ ~ << >>(注意:这些曾经被强制为 32 位宽,但现在在整个本机宽度上操作。)
`vec()`
请注意,除非您有情况 (a),否则您将必须使用 -Duse64bitint Configure 标志配置和编译 Perl。
NOTE: The Configure flags -Duselonglong and -Duse64bits have been
deprecated. Use -Duse64bitint instead.
实际上有两种 64 位模式:第一种是使用 Configure -Duse64bitint 实现的,第二种是使用 Configure -Duse64bitall 实现的。区别在于第一种是最小的,第二种是最大的。第一种在比第二种更多的地方工作。
`use64bitint` 只做必要的操作,以将 64 位整数引入 Perl(这可能意味着,例如,使用“long longs”),而您的内存可能仍然限制为 2 GB(因为您的指针可能仍然是 32 位)。请注意,名称 `64bitint` 并不意味着您的 C 编译器将使用 64 位 `int`(它可能,但它不必):`use64bitint` 意味着您将能够拥有 64 位宽的标量值。
`use64bitall` 通过尝试将整数(如果可以)、长整数(和指针)也切换为 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 位支持和长双精度支持。
现在,具有 ($$)
原型的 Perl 子例程以及 XSUB 可以用作 sort 子例程。在这两种情况下,要比较的两个元素都作为 @_ 中的普通参数传递。请参阅 "sort" in perlfunc。
对于未原型化的排序子例程,将要比较的元素作为全局变量 $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.
除了 BEGIN
、INIT
、END
、DESTROY
和 AUTOLOAD
之外,名为 CHECK
的子例程现在也具有特殊性。这些子例程在编译期间排队,其行为类似于 END 块,只是它们在编译结束时而不是在执行结束时被调用。它们不能被直接调用。
例如,要匹配字母字符,请使用 /[[: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"。
为了改进哈希值中低阶位的分布,已经对哈希算法进行了小的更改。预计这将对重复序列的键产生更好的性能。
新的格式类型 'Z' 用于打包和解包以 null 结尾的字符串。请参阅 "perlfunc 中的 pack"。
新的格式类型修饰符 '!' 用于打包和解包本机短整型、整型和长整型。请参阅 "perlfunc 中的 pack"。
模板字符 '/' 可用于指定要打包或解包的计数字符串类型。请参阅 "perlfunc 中的 pack"。
模板中的 '#' 字符引入注释,直到行尾。这有助于 pack() 模板的文档化。
在以前的 Perl 版本中,您无法缓存对象,以便在从缓存外部删除最后一个引用时允许删除它们。缓存中的引用将保留对象的引用计数,并且对象永远不会被销毁。
另一个常见的问题是循环引用。当一个对象引用自身时,它的引用计数永远不会降到零,并且它不会在程序即将退出之前被销毁。
弱引用通过允许您“弱化”任何引用来解决此问题,也就是说,使其不计入引用计数。当对对象的最后一个非弱引用被删除时,对象将被销毁,并且对该对象的所有弱引用将自动变为 undef。
要使用此功能,您需要来自 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() 内建函数现在支持子程序名称。如果子程序已声明(即使是隐式声明),则被认为存在。有关示例,请参见 "perlfunc 中的 exists"。
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()
将返回 true。eof()
已更改为具有自己的魔法,它现在会打开 <>
文件。
binmode() 现在接受第二个参数,该参数指定要处理的句柄的规则。目前,在 DOS 派生平台上支持两种伪规则:“:raw” 和 “:crlf”。请参阅 "perlfunc 中的 binmode" 和 open。
-T
文件测试将 UTF-8 编码文件识别为“文本”用于 -T
文件测试的算法已得到增强,可以正确地将 UTF-8 内容识别为“文本”。
在 Unix 和类似平台上,system()、qx() 和 open(FOO, "cmd |") 等通过 fork() 和 exec() 实现。当底层的 exec() 失败时,早期版本没有正确报告错误,因为 exec() 恰好发生在不同的进程中。
子进程现在与父进程通信以了解启动外部命令的错误,这允许这些构造以其通常的错误值返回并设置 $!。
在大多数情况下,全局销毁阶段不再抑制行号。
从除主线程以外的线程中运行的代码发出的诊断信息现在会附带线程 ID。
诊断信息中的嵌入式空字符现在会实际显示出来。在之前的版本中,它们会截断消息。
现在,只有在包 foo
中遇到 sort() 时,$foo::a 和 $foo::b 才会免于“可能的拼写错误”警告。
在解析引号结构时遇到的无法识别的字母转义字符现在会生成警告,因为它们在 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
句柄指向的任何文件,而不是始终发送到底层 C 运行时库的 stderr
。
在支持文件句柄上的 close-on-exec 标志的系统上,如果 $^F
的值可能生效,则现在会为通过 pipe()、socketpair()、socket() 和 accept() 创建的任何句柄设置该标志。早期版本忽略了为使用这些运算符创建的句柄设置标志。请参阅 "perlfunc 中的 pipe"、"perlfunc 中的 socketpair"、"perlfunc 中的 socket"、"perlfunc 中的 accept" 和 "perlvar 中的 $^F"。
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
。
更多潜在的不安全操作会污染其结果以提高安全性。
passwd
和 shell
字段由 getpwent()
、getpwnam()
和 getpwuid()
返回,现在被污染了,因为用户可以影响他们自己的加密密码和登录 shell。
由 shmread()
修改的变量,以及由 msgrcv()
(及其面向对象的接口 IPC::SysV::Msg::rcv
)返回的消息也被污染了,因为其他不受信任的进程可以出于恶意目的修改消息和共享内存段。
裸字原型已被合理化,使其能够用于覆盖接受裸字并以特殊方式解释它们的内置函数,例如 require
或 do
。
原型为 *
的参数现在将在子例程中可见,要么是一个简单的标量,要么是对类型全局的引用。请参阅 "perlsub 中的原型"。
require
和 do
可以被覆盖require
和 do 'file'
操作可以通过将相同名称的子例程导入到当前包中(或通过将它们导入到 CORE::GLOBAL::
命名空间中来全局导入)来在本地覆盖。覆盖 require
也会影响 use
,前提是在编译时可见覆盖。请参阅 "perlsub 中的覆盖内置函数"。
以前,$^X 与 ${"\cX"} 同义,但 $^XY 是语法错误。现在,以控制字符开头的变量名可以任意长。但是,出于兼容性原因,这些变量 *必须* 用显式大括号编写,例如 ${^XY}
。${^XYZ}
与 ${"\cXYZ"} 同义。具有多个控制字符的变量名,例如 ${^XY^Z}
,是非法的。
旧语法没有改变。与以前一样,`^X` 可以是字面控制-X 字符,也可以是两个字符序列 `caret` 加 `X`。当省略大括号时,变量名在控制字符后停止。因此,"$^XYZ"
仍然与 $^X . "YZ"
同义,如前所述。
与以前一样,词法变量不能以控制字符开头。与以前一样,以控制字符开头的变量始终强制在包 `main` 中。所有此类变量都为将来的扩展保留,除了以 ^_
开头的变量,这些变量可以由用户程序使用,并且保证在 Perl 的任何未来版本中都不会获得特殊含义。
-c
开关$^C
是一个布尔值变量,它反映了 Perl 是否在仅编译模式下运行(即通过 -c
开关)。由于 BEGIN 代码块在这样的条件下执行,因此此变量使 Perl 代码能够确定是否需要在正常运行期间才有效的操作。参见 perlvar。
$^V
包含 Perl 版本号,以字符串形式表示,其字符的序号与版本号匹配,例如 v5.6.0。这可以在字符串比较中使用。
参见 Support for strings represented as a vector of ordinals
获取示例。
如果 Perl 在定义了 cpp 宏 PERL_Y2KWARN
的情况下构建,它会在将数字 19 与另一个数字连接时发出可选警告。
此行为必须在运行 Configure 时明确启用。参见 INSTALL 和 README.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。
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() 现在返回对包含测试结果的 Benchmark 对象哈希的引用,并以测试名称作为键。
timethis() 现在返回 Benchmark 结果对象中的迭代字段,而不是 0。
timethese()、timethis() 和新的 cmpthese()(见下文)也可以接受“none”的格式说明符以抑制输出。
新函数 countit() 与 timeit() 相同,只是它接受 TIME 而不是 COUNT。
新函数 cmpthese() 打印一个图表,比较从 timethese() 调用返回的每个测试的结果。对于每对可能的测试,都会显示百分比速度差异(迭代/秒或秒/迭代)。
有关其他详细信息,请参见 基准测试。
ByteLoader 是一个专门的扩展,用于生成和运行 Perl 字节码。参见 ByteLoader。
现在可以使用引用。
新版本还允许常量名称以下划线开头,但不允许以双下划线开头(如 "__LINE__")。一些其他名称不允许使用或会发出警告,包括 BEGIN、END 等。一些以前在某些情况下会静默失败的名称(强制使用 main::),现在会引发致命错误(在 main:: 之外)并发出可选警告(在 main:: 之内)。添加了检测常量是否已使用给定名称设置的功能。
参见 constant。
此 pragma 实现 \N
字符串转义。参见 charnames。
可以指定 Maxdepth
设置以避免深入到深层数据结构中。参见 Data::Dumper。
如果 Useqq
设置未启用,则现在会自动调用 Dump() 的 XSUB 实现。
转储 qr//
对象可以正常工作。
DB
是一个实验性模块,它为 Perl 的调试 API 提供了一个干净的抽象。
DB_File 现在可以使用 Berkeley DB 版本 1、2 或 3 构建。参见 ext/DB_File/Changes
。
已添加 Devel::DProf,这是一个 Perl 源代码分析器。参见 Devel::DProf 和 dprofpp。
Devel::Peek 模块提供了对 Perl 变量和数据的内部表示的访问。它是一个用于 XS 程序员的数据调试工具。
Dumpvalue 模块提供了 Perl 数据的屏幕转储。
DynaLoader 现在支持在支持使用 dlclose() 卸载共享对象的平台上使用 dl_unload_file() 函数。
Perl 还可以选择性地安排卸载 Perl 加载的所有扩展共享对象。要启用此功能,请使用 Configure 选项 -Accflags=-DDL_UNLOAD_ALL_AT_EXIT
构建 Perl。(如果您使用的是带有 mod_perl 的 Apache,这可能很有用。)
$PERL_VERSION 现在代表 $^V
(字符串值),而不是 $]
(数值)。
Env 现在支持将 PATH 等环境变量作为数组变量访问。
添加了更多 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
标签使用。
添加了 compare_text() 函数,它允许使用自定义比较函数。请参阅 File::Compare。
当 wanted() 函数是自动加载的或符号引用时,File::Find 现在可以正常工作。
修复了导致 File::Find 在修剪顶层目录时丢失工作目录跟踪的错误。
File::Find 现在还支持其他几个选项来控制其行为。如果指定了 follow
选项,它可以跟踪符号链接。启用 no_chdir
选项将使 File::Find 在遍历目录时跳过更改当前目录。当启用 taint 检查时,untaint
标志可能很有用。
请参阅 File::Find。
此扩展实现了 BSD 风格的文件通配符。默认情况下,它也将用于 glob() 运算符的内部实现。请参阅 File::Glob。
File::Spec 模块中添加了新方法:devnull() 返回空设备的名称(在 Unix 上为 /dev/null),tmpdir() 返回临时目录的名称(在 Unix 上通常为 /tmp)。现在还有用于在绝对文件名和相对文件名之间转换的方法:abs2rel() 和 rel2abs()。为了与在文件路径中指定卷名的操作系统兼容,添加了 splitpath()、splitdir() 和 catdir() 方法。
新的 File::Spec::Functions 模块为 File::Spec 模块提供了一个函数接口。允许使用简写
$fullname = catfile($dir1, $dir2, $file);
代替
$fullname = File::Spec->catfile($dir1, $dir2, $file);
Getopt::Long 的许可证已更改,允许使用 Perl Artistic License 和 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。
已修复一个错误,该错误阻止非选项回调 <> 被指定为第一个参数。
要将字符 < 和 > 指定为选项起始符,请使用 ><。但是,请注意,更改选项起始符强烈不建议。
为了与 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 现在在失败时正确设置 $!。$@ 仍然为了向后兼容而设置。
Java Perl Lingo 现在与 Perl 一起分发。有关更多信息,请参阅 jpl/README。
use lib
现在会剔除任何尾随的重复条目。no lib
会删除所有命名的条目。
现在支持大整数上的按位运算 <<
、>>
、&
、|
和 ~
。
访问器方法 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"
参数的值。
添加了一些径向三角学(圆柱形和球形)、径向坐标转换和大地圆距离。
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::Parser 和 Pod::InputObjects。
此实用程序根据 perlpod 检查 pod 文件的语法是否正确。明显的错误会被标记出来,而警告则会针对可以优雅处理的错误打印出来。检查清单尚未完成。参见 Pod::Checker。
这些模块提供了一组主要对 pod 翻译器有用的工具。 Pod::Find 遍历目录结构并返回找到的 pod 文件及其规范名称(如 File::Spec::Unix
)。 Pod::ParseUtils 包含 Pod::List(用于存储 pod 列表信息)、Pod::Hyperlink(用于解析 L<>
序列的内容)和 Pod::Cache(用于缓存有关 pod 文件的信息,例如链接节点)。
Pod::Select 是 Pod::Parser 的子类,它提供了一个名为“podselect()”的函数,用于从输入流中过滤掉用户指定的原始 pod 文档部分。podselect 是一个脚本,它允许其他脚本访问 Pod::Select,用作过滤器。参见 Pod::Select。
Pod::Usage 提供了“pod2usage()”函数,用于根据 Perl 脚本的嵌入式 pod 文档打印其使用信息。pod2usage() 函数通常对所有脚本作者都有用,因为它允许他们为文档编写和维护一个单一来源(pod),从而无需创建和维护由 pod 中已有的信息组成的冗余使用信息文本。
还有一个 pod2usage 脚本,它可以从其他类型的脚本中使用,用于打印 pod 的使用信息(即使对于嵌入注释中的 pod 的非 Perl 脚本)。
有关详细信息和示例,请参阅 Pod::Usage。
Pod::Text 已重写为使用 Pod::Parser。虽然 pod2text() 仍然为了向后兼容而可用,但该模块现在有一个新的首选接口。有关详细信息,请参阅 Pod::Text。新的 Pod::Text 模块很容易被子类化以调整输出,并且现在有两个这样的子类(Pod::Text::Termcap 用于使用 termcap 信息的 man 页面风格的粗体和下划线,以及 Pod::Text::Color 用于使用 ANSI 颜色序列进行标记)是标准的。
pod2man 已被转换为一个模块 Pod::Man,它也使用 Pod::Parser。在此过程中,已修复了与节标题中的引号、代码转义的引用和嵌套列表相关的几个突出错误。pod2man 现在是围绕此模块的包装脚本。
此模块中添加了一个 EXISTS 方法(并且 sdbm_exists() 已添加到底层 sdbm 库中),因此现在可以对绑定到哈希的 SDBM_File 调用 exists 并获得正确的结果,而不是运行时错误。
已修复一个错误,该错误可能在一次 FETCH() 中从数据库读取多个磁盘块时导致数据丢失。
Sys::Syslog 现在使用 XSUB 来访问 syslog.h 中的设施,因此它不再需要 syslog.ph 存在。
Sys::Hostname 现在使用 XSUB 来调用 C 库的 gethostname() 或 uname()(如果存在)。
Term::ANSIColor 是一个非常简单的模块,用于提供对大多数 ANSI 终端模拟器支持的 ANSI 颜色和突出显示转义序列的简单易读的访问。它现在已包含在标准中。
当日期超出机器的整数范围时,timelocal() 和 timegm() 函数以前会静默地返回虚假结果。如果日期落在不受支持的范围内,它们现在会一致地 croak()。
所有返回值列表的函数的错误返回值已更改。以前这些函数在发生错误时返回一个包含单个元素undef
的列表。现在这些函数在这些情况下返回空列表。这适用于以下函数
Win32::FsType
Win32::GetOSVersion
其余函数保持不变,即使在列表上下文中,在出错时也继续返回undef
。
已添加 Win32::SetLastError(ERROR) 函数作为 Win32::GetLastError() 函数的补充。
新的 Win32::GetFullPathName(FILENAME) 在标量上下文中返回 FILENAME 的完整绝对路径名。在列表上下文中,它返回一个包含完整限定目录名和文件名 的两个元素列表。参见 Win32。
XSLoader 扩展是 DynaLoader 的更简单替代方案。参见 XSLoader。
所有 DBM 模块(DB_File、GDBM_File、NDBM_File、ODBM_File 和 SDBM_File)都添加了一项名为“DBM 过滤器”的新功能。DBM 过滤器为每个 DBM 模块添加了四种新方法
filter_store_key
filter_store_value
filter_fetch_key
filter_fetch_value
这些方法可用于在将键值对写入数据库之前或从数据库读取键值对之后对它们进行过滤。有关更多信息,请参见 perldbmfilter。
use attrs
现已过时,仅出于向后兼容性而提供。它已被 sub : attributes
语法取代。参见 "perlsub 中的子例程属性" 和 attributes。
词法警告 pragma,use warnings;
,用于控制可选警告。参见 perllexwarn。
use filetest
用于控制文件测试的行为(-r
-w
...)。目前仅实现了一个子 pragma,“use filetest 'access';”,它使用 access(2) 或等效方法来检查权限,而不是像往常一样使用 stat(2)。这在具有 ACL(访问控制列表)的文件系统中很重要:stat(2) 可能会撒谎,但 access(2) 更了解情况。
open
pragma 可用于指定句柄构造函数(例如 open())和 qx// 的默认规则。目前,在 DOS 派生平台(即 binmode 不是无操作的地方)上支持两种伪规则 :raw
和 :crlf
。另请参见 "binmode() 可用于设置 :crlf 和 :raw 模式"。
dprofpp
用于显示使用 Devel::DProf
生成的性能分析数据。参见 dprofpp。
find2perl
工具现在使用 File::Find 模块的增强功能。支持 -depth 和 -follow 选项。脚本中也包含了 Pod 文档。
h2xs
工具现在可以与 C::Scan
(可从 CPAN 获取)协同工作,自动解析真实世界的头文件。-M
、-a
、-k
和 -o
选项是新增的。
perlcc
现在支持 C 和字节码后端。默认情况下,它从简单的 C 后端生成输出,而不是优化的 C 后端。
对非 Unix 平台的支持得到了改进。
perldoc
已经过重新设计,以避免潜在的安全漏洞。默认情况下,它不会以超级用户身份运行,但您仍然可以使用 -U 开关尝试使其先放弃权限。
perl5db.pl(Perl 调试器)添加了许多错误修复和增强功能。帮助文档已重新排列。新命令包括 < ?
、> ?
和 { ?
用于列出当前操作,man docpage
用于在某些 perl 文档集中运行您的文档查看器,以及对带引号选项的支持。帮助信息已重新排列,如果您使用 less 作为您的分页器,应该可以再次查看。一个严重的漏洞已被修复——您应该立即从您的系统中删除所有旧版本的 Perl 调试器,包括从 perl3 开始的所有版本,以避免受到此漏洞的影响。
许多特定于平台的 README 文件现在是 perl 安装的一部分。参见 perl 以获取完整列表。
官方的公共 Perl API 函数列表。
面向对象的 Perl 初学者教程。
使用 Perl 编译器套件的介绍。
关于使用 DBM 过滤器功能的说明文档。
所有与运行 Perl 调试器无关的材料,以及所有可能压垮调试器普通用户的低级细节,都已从旧的手册页中迁移到下面的下一项。
这个新的手册页包含与 Perl 调试器无关的过低级的材料,但与调试 Perl 本身略有关系。它还包含一些关于调试过程如何工作的深奥的内部细节,这些细节可能只对 Perl 调试器开发人员感兴趣。
Windows 平台当前提供的 fork() 模拟的说明。
编写 Perl 源代码过滤器的介绍。
一些关于修改 Perl 源代码的指南。
Perl 源代码中内部函数的列表。(列表目前为空。)
关于词法作用域警告类别的介绍和参考信息。
关于 Perl 中数字表示方式的详细信息。
关于有效使用 open() 的教程。
介绍引用基础知识的教程。
关于管理对象模块的类数据的教程。
讨论将来可能在 Perl 中支持的最常被需要的功能。
Perl 中 Unicode 支持功能的介绍。
许多使用简单内联块的常见 sort() 操作现在已针对更快的性能进行了优化。
赋值语句 RHS 中的某些操作已针对直接设置 LHS 上的词法变量进行了优化,从而消除了冗余的复制开销。
子程序调用处理方式的细微变化在内部提供了边际性能改进。
delete()、each()、values() 和列表上下文中哈希返回的哈希值是哈希中的实际值,而不是副本。这在大多数情况下消除了不必要的复制,从而显著提高了性能。
-Dusethreads 标志现在默认情况下启用实验性的基于解释器的线程支持。要获得 5.005 中实验性线程的风格,您需要使用“-Dusethreads -Duse5005threads”运行 Configure。
截至 v5.6.0,解释器线程支持仍然缺乏从 Perl 创建新线程的方法(即,use Thread;
无法与解释器线程一起使用)。use Thread;
在您为 Configure 指定 -Duse5005threads 选项时仍然可用,包括所有错误。
NOTE: Support for threads continues to be an experimental feature.
Interfaces and implementation are subject to sudden and drastic changes.
以下新的标志可以在 Configure 命令行上启用,方法是在运行 Configure 时使用 -Dflag
。
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 位使用的 Configure 选项现在更大胆,因为它们不再具有已知线程/64 位功能的操作系统的显式列表。换句话说:如果您的操作系统具有必要的 API 和数据类型,您应该能够直接使用它们,对于线程,通过 Configure -Dusethreads,对于 64 位,可以通过 Configure -Duse64bitint 显式使用,或者如果您的系统具有 64 位宽数据类型,则隐式使用。另请参阅 "64 位支持"。
某些平台具有“长双精度”,浮点数的范围甚至比普通的“双精度”更大。要启用将长双精度用于 Perl 的标量,请使用 -Duselongdouble。
您可以使用 -Dusemorebits 启用 -Duse64bitint 和 -Duselongdouble。另请参阅 "64 位支持"。
某些平台支持能够处理大型文件(通常,大于 2 GB 的文件)的系统 API。如果您请求 -Duselargefiles,Perl 将尝试使用这些 API。
有关更多信息,请参阅 "大型文件支持"。
您可以使用“Configure -Uinstallusrbinperl”,这会导致 installperl 跳过将 perl 也安装为 /usr/bin/perl。如果您出于某种原因不想修改 /usr/bin,这很有用,但有害,因为许多脚本假设在 /usr/bin/perl 中找到 Perl。
您可以使用“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。
在许多平台上,供应商提供的 'cc' 太简陋了,无法构建 Perl(基本上,'cc' 不支持 ANSI C)。如果情况似乎如此,并且 'cc' 似乎不是 GNU C 编译器 'gcc',则会自动尝试查找并使用 'gcc'。
现在,线程扩展支持 Mach CThreads(NEXTSTEP、OPENSTEP)。
现在支持 GNU/Hurd。
现在支持 Rhapsody/Darwin。
现在支持 EPOC(在 Psion 5 上)。
cygwin 移植(以前称为 cygwin32)已得到极大改进。
Perl 现在可以使用 djgpp 2.02(以及 2.03 alpha)。
环境变量名称不再转换为大写。
已修复反引号中不正确的退出代码。
此移植继续使用其自己的内置通配符(而不是 File::Glob)。
此版本未更新对该 EBCDIC 平台的支持。由于 Perl 将 UTF-8 作为其内部字符表示标准化,而 UTF-8 与 EBCDIC 字符集不兼容,因此在协调两者方面存在困难。
尚不清楚未来版本是否会恢复对该平台的支持,但可能性存在。
对配置、构建、测试和安装过程进行了大量修订和扩展,以适应核心更改和 VMS 特定选项。
扩展 %ENV 处理代码以允许在运行时映射到逻辑名称、CLI 符号和 CRTL environ 数组。
扩展子进程调用代码以接受文件规范作为命令“动词”。
在 Perl 命令行处理中添加了使用默认文件类型和识别 Unix 风格的 2>&1
的功能。
扩展了 File::Spec::VMS 过程,并将其集成到 ExtUtils::MM_VMS 中。
扩展了 ExtUtils::MM_VMS 以更灵活地处理复杂的扩展。
Unix 语法路径开头的裸词可以被视为文本,而不仅仅是逻辑名称。
可选地安全转换 Perl 内部使用的几个逻辑名称。
对新核心代码进行各种错误修复和移植到 VMS。
感谢许多为 VMS 提供补丁、测试和想法的人。
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。
当 $/
设置为 undef
时,"吸取"一个空文件返回一个长度为零的字符串(而不是 undef
,如以前一样),这是在 $/
设置为 undef
后第一次读取 HANDLE。进一步读取将产生 undef
。
这意味着以下操作将把“foo”追加到一个空文件中(以前什么也不做)。
perl -0777 -pi -e 's/^/foo/' empty_file
的行为
perl -pi -e 's/^/foo/' empty_file
保持不变(它仍然保持文件为空)。
eval '...'
增强在涉及 here 文档的情况下,eval '...'
中的代码行号(如 caller() 和大多数诊断信息所反映)通常不正确。此问题已得到修复。
在自身被 eval '...'
调用的函数中,对出现在 eval '...'
中的变量进行词法查找时,会错误地搜索词法范围。现在,词法搜索会在子例程的块边界处正确结束。
在 eval {...}
中使用 return
会导致在 eval 中没有发生异常时,$@ 无法正确重置。此问题已得到修复。
当 here 文档作为 eval 's/.../.../e'
中的替换表达式出现时,对它们的解析存在缺陷。此问题已得到修复。
在编译时遇到的一些“错误”出于必要性被生成为警告,然后最终终止程序。这使得可以在一次运行中报告更多此类错误,而不是在遇到第一个错误时就停止执行。
报告此类错误的机制已重新实现,以便将编译时错误排队,并在编译结束时将它们报告为真正的错误,而不是警告。这修复了在使用 eval STRING
在运行时编译代码时,错误消息以警告形式泄漏的情况,并且还允许使用 eval "..."
可靠地捕获此类错误。
有时,隐式关闭的文件句柄(例如,当它们被局部化时,Perl 会在退出作用域时自动关闭它们)可能会意外地设置 $? 或 $!。此问题已得到修复。
当对文字列表(而不是对数组或哈希进行切片)进行切片时,如果结果恰好由所有 undef 值组成,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
编译指示时,先前版本中以 -
开头的裸字的自动引用不起作用。此问题已修复。
在早期版本的 Perl 中,如果析构函数中的代码抛出异常,则不会被注意到,除非有人碰巧在析构函数运行后立即查看 $@。现在,当启用警告时,此类错误将显示为警告。
以前,printf() 和 sprintf() 会将数字区域设置重置为默认的“C”区域设置。此问题已修复。
根据本地数字区域设置格式化的数字(例如使用小数点而不是小数点)会导致“不是数字”警告,即使访问这些数字的操作产生了正确的结果。这些警告已被取消。
eval 'return sub {...}'
结构有时会导致内存泄漏。此问题已修复。
在无效的文件句柄上使用时,不是文件句柄构造函数的操作会导致内存泄漏。此问题已修复。
修改 @_
的结构可能无法释放 @_
中的值,从而导致内存泄漏。此问题已修复。
当在包中找不到子程序时,Perl 有时会创建空的子程序存根。此类情况阻止了后续的方法查找进入基包。此问题已修复。
-U
下的污染错误在不安全模式下运行时,污染违规有时会导致静默失败。此问题已修复。
-c
开关以前版本在 Perl 以仅编译模式运行时会运行 BEGIN **和** END 块。由于这通常不是预期的行为,因此当使用 -c
开关或编译失败时,END 块不再执行。
有关在编译阶段结束时如何运行内容,请参阅 "支持 CHECK 块"。
使用 __DATA__
标记会为包含该标记的文件创建隐式文件句柄。程序有责任在完成读取后关闭它。
此注意事项现在在文档中得到了更好的解释。请参阅 perldata。
(W misc) 在当前作用域或语句中重新声明了 "my" 或 "our" 变量,有效地消除了对先前实例的所有访问。这几乎总是打字错误。请注意,较早的变量将一直存在到作用域结束或所有对它的闭包引用被销毁为止。
(F) 词法作用域子例程尚未实现。现在不要尝试。
(W misc) 您似乎已经在当前词法作用域中声明了相同的全局变量。
(F) '!' 仅在 pack() 和 unpack() 中某些类型之后允许。请参阅 "pack" in perlfunc。
(F) 您有一个解包模板指示一个计数长度的字符串,但您也为字符串指定了显式大小。请参阅 "perlfunc 中的 pack"。
(F) 您有一个解包模板指示一个计数长度的字符串,它必须后跟字母 a、A 或 Z 中的一个,以指示要解包的字符串类型。请参阅 "perlfunc 中的 pack"。
(F) 您有一个打包模板指示一个计数长度的字符串,目前唯一可以计数其长度的是 a*、A* 或 Z*。请参阅 "perlfunc 中的 pack"。
(F) 您有一个包含 '#' 的解包模板,但它没有遵循一些数字解包规范。请参阅 "perlfunc 中的 pack"。
(W regexp) 您使用了 Perl 不识别的反斜杠字符组合。此组合出现在插值的变量或 '
分隔的正则表达式中。该字符被理解为字面意义。
(W regexp) 您在字符类中使用了 Perl 不识别的反斜杠字符组合。该字符被理解为字面意义。
(W syntax) 您使用了一个模式,Perl 预期在其中找到一个字符串,例如 join
的第一个参数。Perl 将把模式与 $_ 匹配的真或假结果视为字符串,这可能不是您想要的。
(W prototype) 您调用了一个具有原型的函数,但在解析器看到它的定义或声明之前,Perl 无法检查调用是否符合原型。您需要在问题子例程中添加一个早期的原型声明,或者将子例程定义移到调用之前以获得正确的原型检查。或者,如果您确定正在正确调用函数,可以在名称之前放置一个与号以避免警告。请参阅 perlsub。
(F) exists() 的参数必须是哈希或数组元素,例如
$foo{$bar}
$ref->{"susie"}[12]
(F) delete() 的参数必须是哈希或数组元素,例如
$foo{$bar}
$ref->{"susie"}[12]
或散列或数组切片,例如
@foo[$bar, $baz, $xyzzy]
@{$ref->[12]}{"susie", "queue"}
(F) exists &sub
的 exists()
参数必须是子程序名称,而不是子程序调用。exists &sub()
将生成此错误。
(W reserved) 使用了一个小写属性名称,该名称具有包特定的处理程序。该名称将来可能对 Perl 本身有意义,即使它现在还没有。也许您应该使用混合大小写属性名称。参见 属性。
(W misc) 此前缀通常表示 DESTROY() 方法引发了指示的异常。由于析构函数通常在执行过程中的任意点由系统调用,并且通常调用大量次数,因此警告仅针对会导致相同消息重复的任何数量的失败发出一次。
使用 G_KEEPERR
标志分派的使用者回调失败也可能导致此警告。参见 "G_KEEPERR" 在 perlcall 中。
(F) 您写了 require <file>
,而应该写 require 'file'
。
(F) 您尝试从自身内部加入线程,这是不可能的任务。您可能正在加入错误的线程,或者您可能需要将 join() 移动到其他线程。
(F) 您使用了 /e 开关来评估替换,但 perl 在要评估的代码中发现了一个语法错误,最有可能是一个意外的右大括号 '}'.
(S) 一个内部例程在从未被 malloc() 过的东西上调用了 realloc()。强制性,但可以通过将环境变量 PERL_BADFREE
设置为 1 来禁用。
(W bareword) 编译器在预期条件的地方找到了一个裸字,这通常表示 || 或 && 被解析为前一个构造的最后一个参数的一部分,例如
open FOO || die;
这可能也表明一个拼写错误的常量被解释为一个裸字。
use constant TYPO => 1;
if (TYOP) { print "foo" }
strict
编译指示对于避免此类错误非常有用。
(W portable) 您指定的二进制数大于 2**32-1 (4294967295),因此在不同系统之间不可移植。有关可移植性问题的更多信息,请参见 perlport。
(W portable) 使用大于 32 的位向量大小是非便携的。
(W internal) VMS 特有的警告。当 Perl 准备迭代 %ENV 时,它遇到一个过长的逻辑名称或符号定义,因此它被截断为显示的字符串。
(P) 由于某种原因,您无法检查脚本的文件系统以获取 nosuid。
(S) 目前,只有标量变量可以在 "my" 或 "our" 声明中使用特定类限定符声明。语义可能会在将来扩展到其他类型的变量。
(F) 只有标量、数组和哈希变量可以声明为 "my" 或 "our" 变量。它们必须具有普通标识符作为名称。
(W signal) Perl 检测到它正在运行时禁用了 SIGCHLD 信号(有时称为 SIGCLD)。由于禁用此信号会干扰对子进程退出状态的正确确定,因此 Perl 已将信号重置为其默认值。这种情况通常表明 Perl 可能在其下运行的父程序(例如 cron)非常粗心。
(F) 旨在在左值上下文中使用的子例程应声明为左值子例程,请参见 "perlsub 中的左值子例程"。
(S) VMS 特有的警告。Perl 尝试从 CRTL 的内部环境数组中读取 %ENV 的一个元素,并发现该数组丢失。您需要弄清楚您的 CRTL 在哪里放错了其环境,或者定义 PERL_ENV_TABLES(请参见 perlvms),以便不再搜索环境。
(S) 您请求了原地编辑,但没有创建备份文件。Perl 无法删除原始文件以用修改后的文件替换它。文件保持未修改。
(F) Perl 检测到尝试从用作左值的子例程返回非法左值(例如临时值或只读值)。这是不允许的。
(F) 您尝试削弱非引用。只有引用可以被削弱。
(F) 字符类 [: :] 语法中的类未知。请参阅 perlre。
(W unsafe) 字符类构造 [: :], [= =] 和 [. .] 位于字符类内部,[] 是构造的一部分,例如:/[012[:alpha:]345]/. 请注意,[= =] 和 [. .] 目前尚未实现;它们只是未来扩展的占位符。
(F) 常量值(可能使用 use constant
编译指示声明)正在被解引用,但它相当于错误类型的引用。消息指示了预期类型的引用。这通常表示解引用常量值的语法错误。请参阅 "perlsub 中的常量函数" 和 constant。
(F) 解析器在尝试定义重载常量或尝试查找在 \N{...}
转义中指定的字符名称时发现不一致。也许您忘记加载相应的 overload
或 charnames
pragma?请参阅 charnames 和 overload。
(F) CORE:: 命名空间保留用于 Perl 关键字。
(D) defined() 通常对数组没有用,因为它检查未定义的标量值。如果您想查看数组是否为空,只需使用 if (@array) { # 不为空 }
例如。
(D) defined() 通常对哈希没有用,因为它检查未定义的标量值。如果您想查看哈希是否为空,只需使用 if (%hash) { # 不为空 }
例如。
请参阅服务器错误。
(W misc) 请记住,“our”不会本地化声明的全局变量。您在同一个词法范围内再次声明了它,这似乎是多余的。
请参阅服务器错误。
(F) 在 use filetest
pragma 下,切换真实和有效 uid 或 gid 失败。
(W regexp) 字符类范围必须以一个字面字符开始和结束,而不是另一个字符类,例如 \d
或 [:alpha:]
。您错误范围中的“-”被解释为字面“-”。考虑引用“-”,“\-”。请参阅 perlre。
(W io) 您尝试从仅为写入打开的文件句柄中读取。如果您希望它是一个读/写文件句柄,您需要使用“+<”或“+>”或“+>>”而不是“<”或什么都没有打开它。如果您只打算从文件中读取,请使用“<”。请参阅 "perlfunc 中的 open"。
(W closed) 你尝试 flock() 的文件句柄在一段时间前被关闭了。检查你的逻辑流程。flock() 操作的是文件句柄。你是否尝试对同名目录句柄调用 flock()?
(F) 你使用了 "use strict vars",这意味着所有变量必须要么是词法作用域的(使用 "my"),要么事先使用 "our" 声明,要么显式限定以说明全局变量位于哪个包中(使用 "::")。
(W portable) 你指定的十六进制数大于 2**32-1 (4294967295),因此在不同系统之间不可移植。有关可移植性问题的更多信息,请参阅 perlport。
(W internal) VMS 特有的警告。Perl 尝试读取 CRTL 的内部环境数组,并遇到一个没有使用 =
分隔符来分隔键和值的元素。该元素被忽略。
(W internal) VMS 特有的警告。Perl 在准备迭代 %ENV 时尝试读取逻辑名称或 CLI 符号定义,但没有看到键和值之间的预期分隔符,因此该行被忽略。
(F) 你在二进制数中使用了除 0 或 1 之外的数字。
(W digit) 你可能尝试在二进制数中使用除 0 或 1 之外的数字。二进制数的解释在遇到非法数字之前停止。
(F) vec() 中的位数(第三个参数)必须是 1 到 32 的 2 的幂(或者 64,如果你的平台支持)。
(W overflow) 您指定的十六进制、八进制或二进制数字(作为字面量或作为 hex() 或 oct() 的参数)对于您的体系结构来说太大,并且已转换为浮点数。在 32 位体系结构上,可表示的最大十六进制、八进制或二进制数字(不溢出)分别是 0xFFFFFFFF、037777777777 或 0b11111111111111111111111111111111。请注意,Perl 会透明地将所有数字内部提升为浮点数表示形式——在后续操作中可能会出现精度损失错误。
Perl 或用户提供的处理程序无法识别子例程或变量的指定属性。请参阅 属性。
Perl 或用户提供的处理程序无法识别子例程或变量的指定属性。请参阅 属性。
现在已明确显示有问题的范围。
(F) 在属性列表的元素之间看到了冒号或空格以外的字符。如果前面的属性具有带括号的参数列表,则该列表可能过早终止。请参阅 属性。
(F) 在子例程属性列表的元素之间看到了冒号或空格以外的字符。如果前面的属性具有带括号的参数列表,则该列表可能过早终止。
(F) 在 use filetest
pragma 下,切换真实和有效 uid 或 gid 失败。
(F) 由于当前实现的限制,在左值上下文中使用的子例程中无法返回数组和哈希值。请参阅 "perlsub 中的左值子例程"。
请参阅服务器错误。
(F) 字符名文字 \N{charname}
在双引号上下文中语法错误。
(W pipe) 您使用了 open(FH, "| command")
或 open(FH, "command |")
结构,但命令缺失或为空。
(F) 词法作用域子例程的保留语法要求它们具有可以找到的名称。
(F) 指示的命令行开关需要一个必填参数,但您没有指定。
(F) 在 "our" 声明中不允许使用完全限定的变量名,因为这在现有语义下没有意义。此类语法保留用于将来的扩展。
(F) 指示的命令行开关的参数必须紧跟在开关之后,中间不能有空格。
(S) VMS 特有的警告。Perl 无法找到本地时区偏移量,因此假设本地系统时间等效于 UTC。如果不是,请定义逻辑名称 SYS$TIMEZONE_DIFFERENTIAL 以转换为需要添加到 UTC 以获得本地时间的秒数。
(W portable) 您指定的八进制数大于 2**32-1 (4294967295),因此在系统之间不可移植。有关可移植性问题的更多信息,请参阅 perlport。
另请参阅 perlport,了解如何编写可移植代码。
(P) 在尝试重置弱引用时,发生了内部一致性检查失败。
(F) 分叉的子进程返回了关于其 errno 的难以理解的消息。
(P) 在尝试重置对某个对象的全部弱引用时,发生了内部一致性检查失败。
(W parenthesis) 你写了类似这样的代码:
my $foo, $bar = @_;
而你的本意是:
my ($foo, $bar) = @_;
请记住,“my”、“our” 和 “local” 的绑定优先级高于逗号。
(W ambiguous) 以前,Perl 会尝试猜测你想要插值数组还是字面 @。现在它不再这样做;数组现在始终插值到字符串中。这意味着,如果你尝试类似这样的代码:
print "[email protected]";
并且数组 @example
不存在,Perl 将打印 fred.com
,这可能不是你想要的。要在字符串中获得字面 @
符号,请在它前面加上反斜杠,就像你想要获得字面 $
符号一样。
(W y2k) 你正在将数字 19 与另一个数字连接起来,这可能是一个潜在的 2000 年问题。
(W deprecated) 你写了类似这样的代码:
sub doit
{
use attrs qw(locked);
}
你应该使用新的声明语法。
sub doit : locked
{
...
use attrs
pragma 现在已过时,仅为了向后兼容而提供。请参阅 "perlsub 中的子程序属性"。
请参阅服务器错误。
(F) 你不能指定一个大的重复计数,以至于它会溢出你的有符号整数。请参阅 "perlfunc 中的 pack"。
(F) 您不能指定一个重复计数,使其大到溢出您的有符号整数。请参阅 "unpack" in perlfunc。
(S) 一个名为 realloc() 的内部例程在已释放的内容上调用。
(W misc) 您尝试削弱一个已经是弱引用的引用。这样做没有任何效果。
(F) 您的系统具有来自 BSD 4.2 的 setpgrp(),它不接受任何参数,这与 POSIX setpgid() 不同,后者接受一个进程 ID 和一个进程组 ID。
(W regexp) 您在没有意义的地方应用了正则表达式量词,例如在零宽度断言上。尝试将量词放在断言内部。例如,匹配 "abc" 且后面跟着三个 "xyz" 的重复的匹配方式是 /abc(?=(?:xyz){3})/
,而不是 /abc(?=xyz){3}/
。
(F) 在 use filetest
编译指示下,我们无法切换真实和有效 uid 或 gid。
(W internal) VMS 特有的警告。您尝试更改或删除 CRTL 内部环境数组的元素,但您的 Perl 副本不是使用包含 setenv() 函数的 CRTL 构建的。您需要使用包含 setenv() 函数的 CRTL 重新构建 Perl,或者重新定义 PERL_ENV_TABLES(请参阅 perlvms),以便环境数组不是导致警告的 %ENV 更改的目标。
(W void) CHECK 或 INIT 块在运行时本身被定义,此时运行它们的机会已经过去。也许您正在使用 require
或 do
加载文件,而您应该使用 use
。或者,也许您应该将 require
或 do
放入 BEGIN 块中。
(F) 3 参数 open() 的第二个参数不在有效模式列表中:<
、>
、>>
、+<
、+>
、+>>
、-|
、|-
。
(P) VMS 特有的错误。Perl 在遍历 %ENV 之前读取了它的值,而其他人将一条消息插入了 Perl 预期的数据流中。有人非常困惑,或者可能试图出于恶意目的破坏 Perl 对 %ENV 的填充。
(W misc) 您使用了 Perl 不识别的反斜杠字符组合。该字符被理解为字面意思。
(F) 词法分析器在解析属性列表时看到了一个左括号,但没有找到匹配的右括号。您可能需要添加(或删除)一个反斜杠字符来使您的括号平衡。参见 属性。
(F) 词法分析器在属性开头发现了一些不是简单标识符的东西,它也不是分号或块的开始。也许您过早地终止了前一个属性的参数列表。参见 属性。
(F) 词法分析器在解析子程序属性列表时看到了一个左括号,但没有找到匹配的右括号。您可能需要添加(或删除)一个反斜杠字符来使您的括号平衡。
(F) 词法分析器在子程序属性开头发现了一些不是简单标识符的东西,它也不是分号或块的开始。也许您过早地终止了前一个属性的参数列表。
(W misc) VMS 特有的警告。Perl 尝试从 CLI 符号表中读取 %ENV 元素的值,并发现结果字符串长度超过 1024 个字符。返回值已被截断为 1024 个字符。
(P) 将 use Module n.n LIST
语句转换为等效的 BEGIN
块的尝试发现版本号存在内部不一致。
sub : attrs
与旧的 use attrs
的兼容性测试。
测试新的环境标量功能(例如:use Env qw($BAR);
)。
测试新的环境数组功能(例如:use Env qw(@PATH);
)。
IO 常量 (SEEK_*, _IO*)。
与目录相关的 IO 方法 (new, read, close, rewind, tied delete)。
具有多宿主主机的 INET 套接字。
IO poll()。
UNIX 套接字。
my ($x,@y,%z) : attrs
和 <sub : attrs> 的回归测试。
文件测试运算符。
验证访问垫片对象(词法变量和临时变量)的运算。
验证 exists &sub
运算。
请注意,任何新增的警告或增强了的老警告**不**被视为不兼容的更改。
由于所有新的警告都必须通过 -w
开关或 warnings
编译指示显式请求,因此最终由程序员负责确保明智地启用警告。
现在所有名为 CHECK 的子程序定义都是特殊的。有关更多信息,请参见 /"Support for CHECK blocks"
。
完全由未定义值组成的列表切片的行为存在潜在的不兼容性。请参见 "列表切片的行为更加一致"。
English 模块现在将 $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 决定的 close-on-exec 行为的影响。
"$$1"
以表示 "${$}1"
不受支持Perl 5.004 不再支持在插值字符串中将 $$1
和类似内容解释为 $$ . "1"
,但仍然允许它。
在 Perl 5.6.0 及更高版本中,"$$1"
始终表示 "${$1}"
。
\(%h)
对值的别名进行操作,而不是副本
delete()、each()、values() 和哈希(例如 \(%h)
)在列表上下文中返回哈希中的实际值,而不是副本(如它们在早期版本中所做的那样)。使用这些构造的典型习惯用法会复制返回的值,但这在创建对返回值的引用时会产生重大差异。在迭代哈希时,哈希中的键仍然作为副本返回。
如果 BITS 参数不是有效的 2 的幂整数,则 vec() 会生成运行时错误。
诊断中大多数对内部 Perl 操作的引用已更改为更具描述性。这可能是程序可能错误地依赖诊断的精确文本以正常运行的问题。
%@
已被移除以前用于累积“后台”错误(例如在 DESTROY() 中发生的错误)的未记录的特殊变量 %@
已被移除,因为它可能导致内存泄漏。
not
运算符现在属于“如果它看起来像函数,它就表现得像函数”规则。
因此,带括号的形式可与 grep
和 map
一起使用。以下结构以前是语法错误,但现在按预期工作
grep not($_), @things;
另一方面,将 not
与文字列表切片一起使用可能不起作用。以下以前允许的结构
print not (1,2,3)[0];
现在需要用额外的括号编写
print not((1,2,3)[0]);
当 not
后面没有括号时,行为保持不变。
(*)
的语义已更改裸字原型 *
的语义已更改。Perl 5.005 始终将简单标量参数强制转换为类型全局变量,这在子例程必须区分简单标量和类型全局变量的情况下没有用。新行为是不将裸字参数强制转换为类型全局变量。该值将始终显示为简单标量或对类型全局变量的引用。
参见 "更实用的裸字原型 (*)"。
如果您的平台是原生 64 位,或者 Perl 已配置为使用 64 位整数,即 $Config{ivsize} 为 8,则位运算符(& | ^ ~ << >>)的行为可能存在潜在的不兼容性。这些运算符在以前的版本中严格地对整数的低 32 位进行操作,但现在对整个原生整数宽度进行操作。特别要注意,一元运算符 ~
在具有不同 $Config{ivsize} 的平台上会产生不同的结果。为了可移植性,请确保在对一元运算符 ~
的结果进行掩码时,将多余的位屏蔽掉,例如 ~$x & 0xffffffff
。
请参阅 "位运算符支持完整的原生整数宽度"。
如 "改进的安全特性" 中所述,Perl 程序中可能存在更多污染源。
为了避免这些新的污染行为,您可以在编译 Perl 时使用 Configure 选项 -Accflags=-DINCOMPLETE_TAINTS
。请注意,生成的 perl 二进制文件可能不安全。
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 中的内存分配"。
PATCHLEVEL
现在是 PERL_VERSION
cpp 宏 PERL_REVISION
、PERL_VERSION
和 PERL_SUBVERSION
现在默认情况下可从 perl.h 中获得,分别反映了基本修订版、补丁级别和子版本。PERL_REVISION
以前没有等效项,而 PERL_VERSION
和 PERL_SUBVERSION
以前分别可用作 PATCHLEVEL
和 SUBVERSION
。
新的名称减少了对 cpp 命名空间的污染,并反映了这些数字在实际应用中所代表的意义。为了兼容性,当显式包含 patchlevel.h(如以前要求的那样)时,仍然支持旧名称,因此此更改不会造成源代码不兼容。
一般来说,此版本的默认构建预计与使用 5.005 版本或其维护版本构建的扩展二进制兼容。但是,由于提示文件使用的默认值发生变化,特定平台可能存在二进制兼容性问题。因此,请务必始终检查平台特定的自述文件,以了解任何相反的说明。
usethreads 或 usemultiplicity 构建不与 5.005 中的相应构建二进制兼容。
在需要显式导出列表的平台(例如 AIX、OS/2 和 Windows)上,默认情况下不会导出纯内部符号,例如解析器函数和运行时操作码。Perl 5.005 过去会导出所有函数,无论它们是否被认为是公共 API 的一部分。
有关公共 API 函数的完整列表,请参阅 perlapi。
从 5.6.1 版本开始,当执行以下代码时,存在已知的泄漏问题
use Tie::Hash;
tie my %tie_hash => 'Tie::StdHash';
...
local($tie_hash{Foo}) = 1; # leaks
64 位构建
在 HP-UX PA64 和 Linux IA64 等平台上的 64 位构建下,lib/b.t 的子测试 #15 可能会失败。该问题仍在调查中。
如果 Perl 被配置为 64 位,则 lib/io_multihomed 测试可能会在 HP-UX 中挂起。由于其他 64 位平台不会在此测试中挂起,因此 HP-UX 存在问题。所有其他测试在 64 位 HP-UX 中通过。该测试尝试创建并连接到“多宿主”套接字(具有多个 IP 地址的套接字)。
请注意,64 位支持仍处于实验阶段。
线程测试失败
lib/thr5005.t 测试的子测试 19 和 20 已知会失败,这是由于 5.005 线程实现中的根本问题。这些不是新的故障——Perl 5.005_0x 存在相同的错误,但没有这些测试。(请注意,对 5.005 风格线程的支持仍然处于实验阶段。)
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,它随操作系统一起提供,并生成良好的代码。
在早期版本的 Perl 中,支持 EBCDIC 环境,例如 OS390(也称为 Open Edition MVS)和 VM-ESA。由于 UTF-8(Unicode)支持所需的更改,Perl 5.6.0 不支持 EBCDIC 平台。
5.6.1 版本改进了对 EBCDIC 平台的支持,但它们尚未完全支持。
在 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 的未来版本中被移除。这些功能包括以下内容
(?{ code })
和 (??{ code })
(W) 在正则表达式字符类 ([]) 中,以 "[: " 开头并以 ":]" 结尾的语法保留用于未来的扩展。如果您需要在正则表达式字符类中表示这些字符序列,只需用反斜杠对方括号进行转义:"\[:" 和 ":\]"。
(W) 这是一个特定于 VMS 的警告。在准备迭代 %ENV 时,遇到一个逻辑名称,它违反了逻辑名称的语法规则。由于它无法正常转换,因此会被跳过,并且不会出现在 %ENV 中。这可能是一个良性事件,因为某些软件包可能会直接修改逻辑名称表并引入非标准名称,或者它可能表明逻辑名称表已损坏。
此错误的描述过去是
(Someday it will simply assume that an unbackslashed @
interpolates an array.)
这一天已经到来,这个致命错误已被移除。它已被一个非致命警告取代。有关详细信息,请参阅 "数组现在始终插值到双引号字符串中"。
(W) 编译器在预期条件的地方找到了一个裸字,这通常表明 || 或 && 被解析为前一个构造的最后一个参数的一部分,例如
open FOO || die;
(F) 当前的正则表达式实现使用短整型作为字符串中的地址偏移量。不幸的是,这意味着如果正则表达式编译后的长度超过 32767,它就会崩溃。通常,当您需要这么大的正则表达式时,可以使用多个语句来实现更好的方法。请参阅 perlre。
(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 新闻组的文章。您也可以在 https://perldotcom.perl5.cn/,Perl 主页上找到信息。
如果您认为您遇到了未报告的错误,请运行随您的发行版提供的 perlbug 程序。确保将您的错误缩减为一个微小但足够的测试用例。您的错误报告以及 perl -V
的输出将被发送到 [email protected],由 Perl 移植团队进行分析。
有关更改的详细信息,请参阅 Changes 文件。
有关如何构建 Perl 的 INSTALL 文件。
有关一般事项的 README 文件。
有关版权信息的 Artistic 和 Copying 文件。
由 Gurusamy Sarathy <[email protected]> 编写,Perl 维护者贡献了许多内容。
请将遗漏或更正发送至 <[email protected]>。