perlvar - Perl 预定义变量
Perl 中的变量名可以有多种格式。通常,它们必须以字母或下划线开头,在这种情况下,它们可以任意长(最多 251 个字符的内部限制),并且可以包含字母、数字、下划线或特殊序列 ::
或 '
。在这种情况下,最后一个 ::
或 '
之前的部分被视为一个 *包限定符*;参见 perlmod。除非 "use utf8"
生效,否则非 ASCII 的 Unicode 字母不被视为字母,并且适用更复杂的规则;有关详细信息,请参见 "perldata 中的标识符解析"。
Perl 变量名也可以是一系列数字、单个标点符号或两个字符的序列:^
(插入符号或上标)后跟任何一个字符 [][A-Z^_?\]
。这些名称都由 Perl 保留用于特殊用途;例如,所有数字名称用于保存正则表达式匹配后由反向引用捕获的数据。
从 Perl v5.6.0 开始,Perl 变量名也可以是带有插入符号的字母数字字符串。这些必须全部使用带花括号的定界变量形式编写,例如 ${^Foo}
;花括号 **不是** 可选的。${^Foo}
表示名称被视为控制-F
后跟两个 o
的标量变量。(有关此变量名拼写形式或指定访问数组或哈希元素的更多信息,请参见 "perldata 中使用花括号的定界变量名")。这些变量保留供 Perl 将来特殊使用,除了以 ^_
(插入符号-下划线)开头的变量。任何以 ^_
开头的名称都不会在 Perl 的任何未来版本中获得特殊含义;因此,这些名称可以在程序中安全使用。但是,$^_
本身 *是* 保留的。
请注意,在插值时,您也 **必须** 使用定界形式来访问此类变量的下标,例如,要访问 @{^CAPTURE}
变量的第一个元素,您将在双引号字符串中写入 "${^CAPTURE[0]}"
,而不是 "${^CAPTURE}[0]"
,这意味着引用一个名为 ${^CAPTURE}
的标量变量,而不是引用由正则表达式引擎填充的魔术 @{^CAPTURE}
数组的索引 0。
以数字或标点符号开头的 Perl 标识符不受 package
声明的影响,始终强制在 main
包中;它们也不受 strict 'vars'
错误的影响。其他一些名称也以这种方式豁免。
ENV STDIN
INC STDOUT
ARGV STDERR
ARGVOUT
SIG
特别是,特殊变量 ${^_XYZ}
始终被认为是在 main
包中,无论当前作用域中是否存在任何 package
声明。
以下名称对 Perl 具有特殊含义。大多数标点符号名称都有合理的助记符,或者在 shell 中有类似物。但是,如果您希望使用长变量名,您只需要在程序开头说
use English;
这将为当前包中的所有短名称创建别名,指向长名称。有些甚至有中等名称,通常借用自 awk。有关更多信息,请参阅 English。
在继续之前,请注意变量的排序顺序。一般来说,我们首先按不区分大小写、几乎是词典顺序的顺序列出变量(忽略 {
或 ^
在单词之前的符号,如 ${^UNICODE}
或 $^T
),尽管 $_
和 @_
会移动到堆栈的顶部。对于具有相同标识符的变量,我们按标量、数组、哈希和裸字的顺序列出它们。
默认的输入和模式搜索空间。以下对等效
while (<>) {...} # equivalent only in while!
while (defined($_ = <>)) {...}
/^Subject:/
$_ =~ /^Subject:/
tr/a-z/A-Z/
$_ =~ tr/a-z/A-Z/
chomp
chomp($_)
以下是 Perl 将假设 $_
的地方,即使您没有使用它
以下函数使用 $_
作为默认参数
abs, alarm, chomp, chop, chr, chroot, cos, defined, eval, evalbytes, exp, fc, glob, hex, int, lc, lcfirst, length, log, lstat, mkdir, oct, ord, pos, print, printf, quotemeta, readlink, readpipe, ref, require, reverse (仅在标量上下文中), rmdir, say, sin, split (用于其第二个参数), sqrt, stat, study, uc, ucfirst, unlink, unpack.
所有文件测试 (-f
, -d
),除了 -t
,它默认为 STDIN。参见 perlfunc 中的 "-X"
模式匹配操作 m//
, s///
和 tr///
(又名 y///
),当在没有 =~
运算符的情况下使用时。
foreach
循环中,如果没有提供其他变量,则为默认的迭代器变量。
grep()
和 map()
函数中的隐式迭代器变量。
given()
的隐式变量。
当 <FH>
, readline
, readdir
或 each
操作的结果作为 while
测试的唯一标准进行测试时,将下一个值或输入记录放置的默认位置。在 while
测试之外,这不会发生。
$_
是一个全局变量。
然而,在 Perl v5.10.0 到 v5.24.0 之间,可以通过编写 my $_
来将其用作词法变量。然后可以使用 our $_
使 $_
在同一作用域内引用全局 $_
。这个实验性功能已被移除,现在会导致致命错误,但你可能会在旧代码中遇到它。
助记符:下划线在某些操作中被理解。
在子程序中,数组 @_
包含传递给该子程序的参数。在子程序内部,@_
是数组操作符 pop
和 shift
的默认数组。
参见 perlsub.
当数组或数组切片被插值到双引号字符串或类似的上下文中,例如 /.../
时,其元素将使用此值分隔。默认值为空格。例如,这
print "The array is: @array\n";
等同于这
print "The array is: " . join($", @array) . "\n";
助记符:在双引号上下文中有效。
运行此脚本的 Perl 进程号。虽然你可以设置此变量,但通常不建议这样做,尽管它对于某些测试目的来说可能非常宝贵。它将在 fork()
调用之间自动重置。
注意 Linux 和 Debian GNU/kFreeBSD 用户:在 Perl v5.16.0 之前,perl 会在 Linux 系统上使用 LinuxThreads 模拟 POSIX 语义,LinuxThreads 是 POSIX 线程的局部实现,后来被 Native POSIX Thread Library (NPTL) 取代。
LinuxThreads 现在在 Linux 上已过时,并且像这样缓存 getpid()
使嵌入 perl 变得不必要地复杂(因为你必须手动更新 $$ 的值),所以现在 $$
和 getppid()
将始终返回与底层 C 库相同的值。
Debian GNU/kFreeBSD 系统也使用 LinuxThreads 直到 6.0 版本,但之后迁移到 FreeBSD 线程语义,这些语义类似于 POSIX。
要查看你的系统是否受到此差异的影响,请检查 getconf GNU_LIBPTHREAD_VERSION | grep -q NPTL
是否返回假值。NTPL 线程保留 POSIX 语义。
助记符:与 shell 相同。
包含正在执行的程序的名称。
在某些(但并非所有)操作系统上,将值分配给$0
会修改ps
程序看到的参数区域。在某些平台上,您可能需要使用特殊的ps
选项或不同的ps
来查看更改。修改$0
更像是指示当前程序状态的一种方式,而不是隐藏您正在运行的程序。
请注意,$0
的最大长度存在平台特定的限制。在最极端的情况下,它可能仅限于原始$0
所占用的空间。
在某些平台上,ps
显示的修改后的名称之后可能存在任意数量的填充,例如空格字符。在某些平台上,这种填充可能会一直扩展到参数区域的原始长度,无论您做什么(例如,Linux 2.2 就是这种情况)。
对于 BSD 用户的说明:设置$0
并不能完全从 ps(1) 输出中删除“perl”。例如,将$0
设置为"foobar"
可能会导致"perl: foobar (perl)"
("perl: "
前缀和 " (perl)" 后缀是否都显示取决于您的确切 BSD 变体和版本)。这是一个操作系统功能,Perl 无能为力。
在多线程脚本中,Perl 会协调线程,以便任何线程都可以修改其$0
的副本,并且更改会对 ps(1) 可见(假设操作系统配合)。请注意,其他线程看到的$0
视图不会改变,因为它们有自己的副本。
如果程序是通过-e
或-E
开关传递给 perl 的,$0
将包含字符串"-e"
。
在 Linux 上,从 perl v5.14.0 开始,除了通过argv[0]
更改 POSIX 名称(perl 从版本 4.000 开始就一直在这样做)之外,还会使用prctl(2)
设置旧的进程名称。现在,读取旧的进程名称的系统实用程序(如 ps、top 和 killall)将识别您在将值分配给$0
时设置的名称。您提供的字符串将在 16 个字节处被截断,这是 Linux 强加的限制。
宽字符在$0
值中无效。但是,出于历史原因,Perl 接受它们并将它们编码为 UTF-8。发生这种情况时,会触发宽字符警告。
助记符:与sh和ksh相同。
此进程的真实 gid。如果您在支持同时加入多个组的机器上,则会提供一个以空格分隔的您所属组的列表。第一个数字是getgid()
返回的数字,随后的数字是getgroups()
返回的数字,其中一个可能与第一个数字相同。
但是,分配给$(
的值必须是一个用于设置真实 gid 的单个数字。因此,$(
给出的值不应该在没有强制转换为数字的情况下分配回$(
,例如通过加零。请注意,这与有效 gid($
)不同,有效 gid 接受列表。
您可以使用 POSIX::setgid()
同时更改真实组 ID 和有效组 ID。对 $(
的更改需要检查 $!
以检测尝试更改后可能出现的任何错误。
助记符:圆括号用于分组事物。真实组 ID 是您离开的组,如果您正在运行 setgid。
此进程的有效组 ID。如果您在支持同时加入多个组的机器上,则会给出您所属组的空格分隔列表。第一个数字是 getegid()
返回的数字,后续数字是 getgroups()
返回的数字,其中一个数字可能与第一个数字相同。
类似地,分配给 $)
的值也必须是空格分隔的数字列表。第一个数字设置有效组 ID,其余数字(如果有)传递给 setgroups()
。要获得 setgroups()
的空列表的效果,只需重复新的有效组 ID;也就是说,要强制有效组 ID 为 5 并且有效为空的 setgroups()
列表,请说 $) = "5 5"
。
您可以使用 POSIX::setgid()
同时更改有效组 ID 和真实组 ID(仅使用单个数字参数)。对 $)
的更改需要检查 $!
以检测尝试更改后可能出现的任何错误。
$<
、$>
、$(
和 $)
只能在支持相应 set[re][ug]id() 例程的机器上设置。$(
和 $)
只能在支持 setregid()
的机器上交换。
助记符:圆括号用于分组事物。有效组 ID 是适合您的组,如果您正在运行 setgid。
此进程的真实用户 ID。您可以使用 POSIX::setuid()
同时更改真实用户 ID 和有效用户 ID。由于对 $<
的更改需要系统调用,因此在尝试更改后检查 $!
以检测任何可能的错误。
助记符:如果您正在运行 setuid,这是您来自的 uid。
此进程的有效用户 ID。例如
$< = $>; # set real to effective uid
($<,$>) = ($>,$<); # swap real and effective uids
您可以使用 POSIX::setuid()
同时更改有效用户 ID 和真实用户 ID。对 $>
的更改需要检查 $!
以检测尝试更改后可能出现的任何错误。
$<
和 $>
只能在支持 setreuid()
的机器上交换。
助记符:如果您正在运行 setuid,这是您去往的 uid。
用于模拟多维数组的下标分隔符。如果您将哈希元素引用为
$foo{$x,$y,$z}
它实际上意味着
$foo{join($;, $x, $y, $z)}
但不要放
@foo{$x,$y,$z} # a slice--note the @
这意味着
($foo{$x},$foo{$y},$foo{$z})
默认值为 "\034",与 awk 中的 SUBSEP 相同。如果您的键包含二进制数据,则可能没有安全的值可用于 $;
。
考虑使用 perllol 中描述的“真实”多维数组。
助记符:逗号(语法下标分隔符)是分号。
使用 sort()
时,特殊包变量,请参阅 "sort" in perlfunc。由于这种特殊性,即使使用 strict 'vars'
准则,$a
和 $b
也无需声明(使用 use vars
或 our()
)。如果您想在 sort()
比较块或函数中使用它们,请不要使用 my $a
或 my $b
对它们进行词法化。
哈希 %ENV
包含您当前的环境。在 ENV
中设置值会更改您随后 fork()
产生的任何子进程的环境。
从 v5.18.0 开始,存储在 %ENV
中的键和值都将被字符串化。
my $foo = 1;
$ENV{'bar'} = \$foo;
if( ref $ENV{'bar'} ) {
say "Pre 5.18.0 Behaviour";
} else {
say "Post 5.18.0 Behaviour";
}
以前,只有子进程会收到字符串化的值
my $foo = 1;
$ENV{'bar'} = \$foo;
# Always printed 'non ref'
system($^X, '-e',
q/print ( ref $ENV{'bar'} ? 'ref' : 'non ref' ) /);
发生这种情况是因为您无法真正与外部进程共享任意数据结构。
Perl 解释器的修订版、版本和子版本,表示为 5.XXXYYY 形式的十进制数,其中 XXX 是版本 / 1e3,YYY 是子版本 / 1e6。例如,Perl v5.10.1 将是“5.010001”。
此变量可用于确定执行脚本的 Perl 解释器是否在正确的版本范围内
warn "No PerlIO!\n" if "$]" < 5.008;
在比较 $]
时,应使用数值比较运算符,但应先将变量字符串化,以避免其原始数值不准确的问题。
另请参阅 use VERSION
和 require VERSION
的文档,了解一种方便的方法,如果运行的 Perl 解释器太旧,则会失败。
参见 "$^V" 以获取 Perl 版本的表示形式,作为 版本 对象,允许更灵活的字符串比较。
$]
相对于 $^V
的主要优势在于它在任何版本的 Perl 上都以相同的方式工作。缺点是它不能轻松地与其他格式的版本进行比较(例如,文字 v 字符串,“v1.2.3”或版本对象),并且数字比较会受到二进制浮点表示的影响;它适用于数字文字版本检查,但不适用于与未经完整性检查的变量进行比较。
$OLD_PERL_VERSION
形式是在 Perl v5.20.0 中出于历史原因添加的,但其使用不鼓励。(如果使用 $]
的原因是在旧的 perl 上运行代码,那么将其称为 $OLD_PERL_VERSION
将适得其反。)
助记符:此版本的 perl 是否在正确的括号中?
最大系统文件描述符,通常为 2。系统文件描述符传递给 exec()
ed 进程,而更高的文件描述符则不会。此外,在 open()
期间,即使 open()
失败,系统文件描述符也会被保留(普通文件描述符会在尝试 open()
之前关闭)。文件描述符的 close-on-exec 状态将根据打开相应文件、管道或套接字时的 $^F
值决定,而不是 exec()
时。
数组 @F
包含在打开自动拆分模式时读取的每一行的字段。有关 -a 开关,请参见 perlrun。此数组是特定于包的,如果在 strict 'vars'
下运行时不在包 main 中,则必须声明或给出完整的包名。
数组 @INC
包含了 do EXPR
、require
或 use
结构查找其库文件的位置列表。它最初包含任何 -I 命令行开关的参数,后面跟着默认的 Perl 库,可能是 /usr/local/lib/perl。在 Perl 5.26 之前,.
(代表当前目录)包含在 @INC
中;它已被移除。此行为更改在 PERL_USE_UNSAFE_INC
中有记录,并且不建议将 .
重新添加到 @INC
中。如果您需要在运行时修改 @INC
,您应该使用 use lib
编译指示来正确加载机器相关的库。
use lib '/mypath/libdir/';
use SomeMod;
您还可以通过将 Perl 代码直接放入 @INC
中来插入文件包含系统中的钩子。这些钩子可以是子例程引用、数组引用或祝福对象。有关详细信息,请参阅 "require" in perlfunc。
哈希 %INC
包含通过 do
、require
或 use
运算符包含的每个文件名的条目。键是您指定的文件名(模块名称转换为路径名),值是找到的文件的位置。require
运算符使用此哈希来确定是否已包含特定文件。
如果文件是通过钩子加载的(例如子例程引用,请参阅 "require" in perlfunc 以了解这些钩子的描述),则默认情况下,此钩子将插入 %INC
中以代替文件名。但是请注意,钩子可能已经自行设置了 %INC
条目以提供一些更具体的信息。
从 5.37.7 开始,当执行 @INC
钩子时,包含钩子的 @INC
数组的索引将被局部化到 $INC
变量中。当钩子返回时,其值的整数后继将用于确定将检查的 @INC
中的下一个索引,因此如果将其设置为 -1(或 undef
),则对 @INC
数组的遍历将从其开头重新开始。
通常,对 @INC
数组的遍历是从头到尾(0 .. $#INC
),如果 @INC
数组被钩子修改,则迭代器可能处于新添加的条目被跳过的状态。更改此值允许 @INC
钩子重写 @INC
数组并告诉 Perl 之后在哪里继续。有关 @INC
钩子的详细信息,请参阅 "require" in perlfunc。
就地编辑扩展的当前值。使用 undef
禁用就地编辑。
助记符:-i 开关的值。
每个包都包含一个名为 @ISA
的特殊数组,该数组包含该类的父类列表(如果有)。此数组只是一个标量列表,每个标量都是一个字符串,对应于一个包名。当 Perl 进行方法解析时,会检查此数组,方法解析在 perlobj 中介绍。
要加载包并将其添加到 @ISA
中,请参阅 parent 句法。不推荐使用的 base 句法也能做到这一点,但除非需要与不推荐使用的 fields 句法兼容,否则不应使用它。
默认情况下,内存不足是一个无法捕获的致命错误。但是,如果 Perl 构建得当,它可以在 die()
后使用 $^M
的内容作为紧急内存池。假设您的 Perl 使用 -DPERL_EMERGENCY_SBRK
编译,并使用 Perl 的 malloc。那么
$^M = 'a' x (1 << 16);
将分配一个 64K 的缓冲区供紧急情况使用。有关在编译 perl 时如何添加自定义 C 编译标志的信息,请参阅 Perl 发行版中的 INSTALL 文件。为了阻止随意使用此高级功能,此变量没有 English 长名称。
此变量是在 Perl 5.004 中添加的。
此变量决定允许的最大 eval EXPR
/BEGIN
或 require
/BEGIN
块嵌套数量。这意味着它也控制 use
语句的最大嵌套数量。
默认值 1000 对于正常工作目的来说应该足够大,如果您必须提高它,那么您应该谨慎选择,否则您可能会遇到由于 C 栈耗尽而导致的段错误。真实代码不太可能使用深度超过 1000,但我们将其设置为可配置,以防万一。
当设置为 0
时,eval EXPR
或 require EXPR
内部的 BEGIN
块将完全禁止,并将触发异常,该异常将终止编译,在 require
的情况下将抛出异常,或在 eval
的情况下按预期在 $@
中返回错误。
考虑以下代码
perl -le'sub f { eval "BEGIN { f() }"; } f()'
每次调用 f()
都会消耗大量的 C 栈,此变量用于使此类代码死亡,而不是耗尽 C 栈并触发段错误。不用说,像这样的代码是不寻常的,您不太可能真正需要提高设置。但是,将其设置为 0 一段时间可能有助于防止 BEGIN{}
块在 eval EXPR
期间执行。
请注意,将其设置为 1 不会影响像这样的代码
BEGIN { $n += 1; BEGIN { $n += 2; BEGIN { $n += 4 } } }
原因是 BEGIN 块在完成编译后立即执行,因此最内层的 BEGIN 块将在包含它的 BEGIN 块完成编译之前执行,并且深度不会超过 1。实际上,上面的代码等效于
BEGIN { $n+=4 }
BEGIN { $n+=2 }
BEGIN { $n+=1 }
这使得很明显为什么 ${^MAX_EVAL_BEGIN_DEPTH} 为 1 不会阻止这段代码。
只有在 eval
或 require
(可能通过 use
)中执行的 BEGIN
会受到影响。
构建此 Perl 副本的操作系统的名称,由配置过程确定。有关示例,请参阅 "PLATFORMS" in perlport。
该值与 $Config{'osname'}
相同。另请参阅 Config 和 perlrun 中记录的 -V 命令行开关。
在 Windows 平台上,$^O
帮助不大:因为它始终为 MSWin32
,它无法区分 95/98/ME/NT/2000/XP/CE/.NET。使用 Win32::GetOSName()
或 Win32::GetOSVersion()(请参阅 Win32 和 perlport)来区分这些变体。
此变量是在 Perl 5.003 中添加的。
哈希 %SIG
包含信号的信号处理程序。例如
sub handler { # 1st argument is signal name
my($sig) = @_;
print "Caught a SIG$sig--shutting down\n";
close(LOG);
exit(0);
}
$SIG{'INT'} = \&handler;
$SIG{'QUIT'} = \&handler;
...
$SIG{'INT'} = 'DEFAULT'; # restore default action
$SIG{'QUIT'} = 'IGNORE'; # ignore SIGQUIT
使用 'IGNORE'
作为值通常会忽略信号,但 CHLD
信号除外。有关此特殊情况的更多信息,请参阅 perlipc。使用空字符串或 undef
作为值与 'DEFAULT'
的效果相同。
以下是一些其他示例
$SIG{"PIPE"} = "Plumber"; # assumes main::Plumber (not
# recommended)
$SIG{"PIPE"} = \&Plumber; # just fine; assume current
# Plumber
$SIG{"PIPE"} = *Plumber; # somewhat esoteric
$SIG{"PIPE"} = Plumber(); # oops, what did Plumber()
# return??
请确保不要使用裸字作为信号处理程序的名称,以免意外调用它。
使用与任何现有函数都不对应的字符串或不包含代码槽的全局变量等效于 'IGNORE'
,但在调用处理程序时会发出警告(对于下面描述的内部钩子,不会发出警告)。
如果您的系统具有 sigaction()
函数,则使用它安装信号处理程序。这意味着您将获得可靠的信号处理。
Perl v5.8.0 中信号的默认传递策略从立即(也称为“不安全”)更改为延迟,也称为“安全信号”。有关更多信息,请参阅 perlipc。
某些内部钩子也可以使用%SIG
哈希设置。当警告消息即将打印时,$SIG{__WARN__}
指示的例程会被调用。警告消息作为第一个参数传递。__WARN__
钩子的存在会导致将警告正常打印到STDERR
被抑制。您可以使用它将警告保存在变量中,或将警告转换为致命错误,例如
local $SIG{__WARN__} = sub { die $_[0] };
eval $proggie;
由于'IGNORE'
钩子不受__WARN__
支持,因此其效果与使用'DEFAULT'
相同。您可以使用空子例程禁用警告
local $SIG{__WARN__} = sub {};
当致命异常即将抛出时,$SIG{__DIE__}
指示的例程会被调用。错误消息作为第一个参数传递。当__DIE__
钩子例程返回时,异常处理将继续进行,就像没有钩子一样,除非钩子例程本身通过goto &sub
、循环退出或die()
退出。__DIE__
处理程序在调用期间被明确禁用,因此您可以从__DIE__
处理程序中退出。__WARN__
也是如此。
即使在eval()
内部,也会调用$SIG{__DIE__}
钩子。它本来不应该这样,但实现中的一个故障使这成为可能。这曾经被弃用,因为它允许在远处进行奇怪的操作,例如在$@
中重写待处理的异常。纠正此问题的计划已被放弃,因为用户发现重写待处理的异常实际上是一个有用的功能,而不是一个错误。
$SIG{__DIE__}
不支持'IGNORE'
;它与'DEFAULT'
具有相同的效果。
__DIE__
/__WARN__
处理程序在某一方面非常特殊:它们可能会被调用来报告解析器发现的(可能的)错误。在这种情况下,解析器可能处于不一致状态,因此从这种处理程序中评估 Perl 代码的任何尝试都可能导致段错误。这意味着,应谨慎使用导致解析 Perl 时的警告或错误,例如
require Carp if defined $^S;
Carp::confess("Something wrong") if defined &Carp::confess;
die "Something wrong, but could not load Carp to give "
. "backtrace...\n\t"
. "To see backtrace try starting Perl with -MCarp switch";
这里,第一行将加载Carp
,除非是解析器调用了处理程序。第二行将打印回溯并退出,如果Carp
可用。第三行仅在Carp
不可用时执行。
即使在异常处理程序中考虑$^S
变量也是错误的。当前实现的$SIG{__DIE__}
会导致严重且难以追踪的错误。避免使用它,而是使用END{}
或 CORE::GLOBAL::die 覆盖。
有关更多信息,请参阅 "perlfunc 中的 die"、"perlfunc 中的 warn"、"perlfunc 中的 eval" 和 警告。
此哈希包含代码引用,这些代码引用在调用各种难以或不可能包装的 Perl 关键字时被调用。此哈希的键以被挂钩的关键字命名,后跟两个下划线,然后是一个阶段术语;要么是“before”要么是“after”。
如果您尝试修改未记录存在的键,或者尝试在哈希中存储除代码引用或 undef 之外的任何内容,Perl 将抛出错误。如果您希望使用对象来实现挂钩,您可以使用柯里化将对象嵌入到匿名代码引用中。
目前只有一个可以挂钩的关键字,require
,但预计在未来的版本中将有更多支持挂钩的关键字。
${^HOOK}{require__before}
指示的例程由 require
在其检查 %INC
、查找 @INC
、调用 INC 挂钩或编译任何代码 **之前** 调用。它使用单个参数调用,即要请求的项目的文件名(包名将转换为路径)。它可以更改此文件名以更改加载的文件。如果挂钩在执行期间死亡,那么它将阻止请求执行。
为了便于在执行 require 关键字之前和之后使用共享状态执行操作,require__before
挂钩可以返回一个“后操作”代码引用,该代码引用将在 require
完成时执行。无论 require 是否成功完成或抛出异常,此代码引用都将被执行。它将使用请求的文件名调用。您可以检查 %INC 以确定请求是否成功。require__before
挂钩的任何其他返回值将被静默忽略。
require__before
钩子按 FIFO 顺序调用,如果钩子返回代码引用,则这些代码引用将按 FILO 顺序调用。换句话说,如果 A 需要 B 需要 C,则 require__before
将首先为 A 调用,然后是 B,然后是 C,并且后操作代码引用将首先为 C 执行,然后是 B,最后是 A。
行为良好的代码应确保在设置 require__before
钩子时,将调用任何先前安装的钩子,并且如果其返回值是代码引用,也将调用其返回值。有关示例实现,请参见 "require" in perlfunc。
${^HOOK}{require__after}
指示的例程由 require
在 require
完成 **后** 调用。它使用单个参数调用,即要要求的项目的文件名(包名将转换为路径)。当 require
完成时执行,无论是通过异常还是通过 require
语句的完成,并且您可以检查 %INC
以确定 require
是否成功。
require__after
钩子按 FILO 顺序为每个所需文件调用。换句话说,如果 A 需要 B 需要 C,则 require__after
将首先为 C 调用,然后是 B,然后是 A。
程序开始运行的时间,以自纪元(1970 年开始)以来的秒数表示。-M、-A 和 -C 文件测试返回的值基于此值。
Perl 解释器的修订版、版本和子版本,表示为 version 对象。
此变量首次出现在 perl v5.6.0 中;早期版本的 perl 将看到未定义的值。在 perl v5.10.0 之前,$^V
表示为 v 字符串而不是 version 对象。
$^V
可用于确定执行脚本的 Perl 解释器是否在正确的版本范围内。例如
warn "Hashes not randomized!\n" if !$^V or $^V lt v5.8.1
虽然版本对象重载字符串化,但要以可移植的方式将 $^V
转换为其字符串表示形式,请使用 sprintf()
的 "%vd"
转换,它适用于 v 字符串或版本对象
printf "version is v%vd\n", $^V; # Perl's version
请参阅 use VERSION
和 require VERSION
的文档,了解一种方便的方法,用于在运行的 Perl 解释器过旧时失败。
另请参阅 "$]"
,了解 Perl 版本的十进制表示。
$^V
相对于 $]
的主要优势在于,对于 Perl v5.10.0 或更高版本,它会重载运算符,允许轻松地与其他版本表示进行比较(例如,十进制、文字 v 字符串、"v1.2.3" 或对象)。缺点是,在 v5.10.0 之前,它只是一个文字 v 字符串,不能轻松打印或比较,而 $]
的行为在所有版本的 Perl 上都保持不变。
助记符:使用 ^V 表示版本对象。
用于执行当前 Perl 副本的名称,来自 C 的 argv[0]
或(在支持的情况下)/proc/self/exe。
根据主机操作系统,$^X
的值可能是 perl 程序文件的相对或绝对路径名,也可能是用于调用 perl 的字符串,而不是 perl 程序文件的路径名。此外,大多数操作系统允许调用不在 PATH 环境变量中的程序,因此不能保证 $^X
的值在 PATH 中。对于 VMS,该值可能包含或不包含版本号。
通常可以使用 $^X
的值重新调用当前正在运行的相同 perl 的独立副本,例如:
@first_run = `$^X -le "print int rand 100 for 1..100"`;
但请记住,并非所有操作系统都支持分叉或捕获命令的输出,因此此复杂语句可能不可移植。
将 $^X
的值用作文件路径名是不安全的,因为某些操作系统对可执行文件具有强制性后缀,但在调用命令时不需要使用该后缀。要将 $^X
的值转换为路径名,请使用以下语句
# Build up a set of file names (not command names).
use Config;
my $this_perl = $^X;
if ($^O ne 'VMS') {
$this_perl .= $Config{_exe}
unless $this_perl =~ m/$Config{_exe}$/i;
}
由于许多操作系统允许任何拥有 Perl 程序文件读取权限的人复制该文件、修补副本,然后执行副本,因此注重安全的 Perl 程序员应该注意调用已安装的 perl 副本,而不是 $^X
引用的副本。以下语句可以实现此目标,并生成可以作为命令调用或作为文件引用的路径名。
use Config;
my $secure_perl_path = $Config{perlpath};
if ($^O ne 'VMS') {
$secure_perl_path .= $Config{_exe}
unless $secure_perl_path =~ m/$Config{_exe}$/i;
}
大多数与正则表达式相关的特殊变量是副作用。Perl 在成功完成匹配后设置这些变量,因此您应该在使用它们之前检查匹配结果。例如
if( /P(A)TT(ER)N/ ) {
print "I found $1 and $2\n";
}
这些变量是只读的,其行为类似于动态作用域变量,只有少数例外情况明确记录为表现不同。有关更多详细信息,请参见下一节。
正则表达式变量允许程序员访问当前动态作用域中最新的成功正则表达式匹配的状态。
变量本身是全局的,没有作用域,但它们访问的数据的作用域类似于动态作用域变量,即每次成功的匹配都表现为将全局状态对象局部化到当前块或文件作用域。(有关动态作用域和 local
关键字的更多详细信息,请参见 "perlsyn 中的复合语句"。)
成功匹配包括搜索和替换运算符 s///
执行的任何成功匹配,以及 m//
运算符执行的匹配。
考虑以下代码
my @state;
sub matchit {
push @state, $1; # pushes "baz"
my $str = shift;
$str =~ /(zat)/; # matches "zat"
push @state, $1; # pushes "zat"
}
{
$str = "foo bar baz blorp zat";
$str =~ /(foo)/; # matches "foo"
push @state, $1; # pushes "foo"
{
$str =~ /(pizza)/; # does NOT match
push @state, $1; # pushes "foo"
$str =~ /(bar)/; # matches "bar"
push @state, $1; # pushes "bar"
$str =~ /(baz)/; # matches "baz"
matchit($str); # see above
push @state, $1; # pushes "baz"
}
$str =~ s/noodles/rice/; # does NOT match
push @state, $1; # pushes "foo"
$str =~ s/(blorp)/zwoop/; # matches "blorp"
push @state, $1; # pushes "blorp"
}
# the following prints "foo, foo, bar, baz, zat, baz, foo, blorp"
print join ",", @state;
请注意,在完全相同的作用域中,每次成功的匹配都会覆盖之前成功匹配的匹配上下文,但失败的匹配不会。还要注意,在内部嵌套作用域中,来自外部动态作用域的先前状态会一直保留,直到被另一个成功的匹配覆盖,但当内部嵌套作用域退出时,在内部成功匹配之前生效的任何匹配上下文都会在作用域结束时恢复。
众所周知,goto LABEL
可能与动态作用域匹配上下文交互不良。这可能无法修复,并且被认为是避免 goto LABEL
的众多充分理由之一。
传统上,在 Perl 中,任何代码中使用三个变量 $`
、$&
或 $'
(或其 use English
等价物)中的任何一个,都会导致所有后续成功的模式匹配都复制匹配的字符串,以防代码随后可能访问其中一个变量。这给整个程序带来了相当大的性能损失,因此通常不鼓励使用这些变量。
在 Perl 5.6.0 中引入了 @-
和 @+
动态数组,它们提供了成功匹配的索引。因此,您可以例如执行以下操作
$str =~ /pattern/;
print $`, $&, $'; # bad: performance hit
print # good: no performance hit
substr($str, 0, $-[0]),
substr($str, $-[0], $+[0]-$-[0]),
substr($str, $+[0]);
在 Perl 5.10.0 中引入了 /p
匹配运算符标志以及 ${^PREMATCH}
、${^MATCH}
和 ${^POSTMATCH}
变量,这些变量允许您仅对标记为 /p
的模式遭受性能损失。
在 Perl 5.18.0 及更高版本中,perl 开始分别记录这三个变量中的每一个的存在,并且只复制所需的字符串部分;因此在
$`; $&; "abcdefgh" =~ /d/
perl 仅复制字符串的 "abcd" 部分。这在类似以下情况中可能会有很大差异
$str = 'x' x 1_000_000;
$&; # whoops
$str =~ /x/g # one char copied a million times, not a million chars
在 Perl 5.20.0 中,默认情况下启用了新的写时复制系统,这最终解决了这三个变量的大部分性能问题,并使其可以在任何地方安全使用。
Devel::NYTProf
和 Devel::FindAmpersand
模块可以帮助您在代码中找到这些有问题的匹配变量的使用。
包含来自当前动态作用域中最后一次成功的模式匹配的相应捕获括号集的子模式。(参见 "正则表达式变量的作用域规则"。)
请注意,匹配空字符串的捕获缓冲区与可选的捕获缓冲区之间存在区别。例如,(x?)
和 (x)?
后者可能是未定义的,前者不是。
这些变量是只读的。
助记符:类似于 \digits。
一个数组,它公开最后一次成功的模式匹配的捕获缓冲区(如果有)的内容,不包括已退出嵌套块中匹配的模式。
请注意,@{^CAPTURE} 的 0 索引等效于 $1,1 索引等效于 $2,等等。
if ("foal"=~/(.)(.)(.)(.)/) {
print join "-", @{^CAPTURE};
}
应该输出 "f-o-a-l"。
另请参阅 "$<digits> ($1, $2, ...)"、"%{^CAPTURE}" 和 "%{^CAPTURE_ALL}"。
请注意,与大多数其他正则表达式魔术变量不同,@{^CAPTURE}
没有单字母等效项。另外,请注意,在插值此数组的下标时,**必须**使用分隔变量形式,例如
print "${^CAPTURE[0]}"
请参阅 "perldata 中使用大括号的分隔变量名",以了解有关此形式及其用法的更多信息。
此变量在 5.25.7 中添加。
由最后一次成功的模式匹配匹配的字符串。(请参阅 "正则表达式变量的作用域规则"。)
请参阅上面的 "性能问题",了解在代码中使用此变量(即使只使用一次)带来的严重性能影响。
此变量是只读的,其值是动态作用域的。
助记符:类似于某些编辑器中的 &
。
只有在模式使用 /p
修饰符编译或执行时,它才保证返回定义的值。
这类似于 $&
($MATCH
),不同之处在于,要使用它,您必须在执行模式时使用 /p
修饰符,并且它不会产生与该变量相关的性能损失。
请参阅上面的 "性能问题"。
此变量在 Perl v5.10.0 中添加。
此变量是只读的,其值是动态作用域的。
位于最后一次成功的模式匹配匹配的字符串之前的字符串。(请参阅 "正则表达式变量的作用域规则")。
请参阅上面的 "性能问题",了解在代码中使用此变量(即使只使用一次)带来的严重性能影响。
此变量是只读的,其值是动态作用域的。
助记符:`
通常位于引号字符串之前。
只有在模式使用 /p
修饰符执行时,它才保证返回定义的值。
这类似于 $`
($PREMATCH),不同之处在于,要使用它,您必须在执行模式时使用 /p
修饰符,并且它不会产生与该变量相关的性能损失。
请参阅上面的 "性能问题"。
此变量在 Perl v5.10.0 中添加。
此变量是只读的,其值是动态作用域的。
最后一次成功模式匹配后匹配到的字符串。 (参见 "正则表达式变量的作用域规则")。 例如
local $_ = 'abcdefghi';
/def/;
print "$`:$&:$'\n"; # prints abc:def:ghi
请参阅上面的 "性能问题",了解在代码中使用此变量(即使只使用一次)带来的严重性能影响。
此变量是只读的,其值是动态作用域的。
助记符:'
通常紧跟在引号字符串之后。
只有在模式使用 /p
修饰符编译或执行时,它才保证返回定义的值。
这与 $'
($POSTMATCH
) 类似,不同之处在于使用它时必须在执行模式时使用 /p
修饰符,并且不会产生与该变量相关的性能损失。
请参阅上面的 "性能问题"。
此变量在 Perl v5.10.0 中添加。
此变量是只读的,其值是动态作用域的。
最后一次成功搜索模式中使用过的最高捕获组匹配的文本。 (参见 "正则表达式变量的作用域规则")。 它在逻辑上等效于具有定义值的最高编号的捕获变量 ($1
, $2
, ...) 。
如果您不知道一组备选模式中的哪一个匹配,这将很有用。 例如
/Version: (.*)|Revision: (.*)/ && ($rev = $+);
此变量是只读的,其值是动态作用域的。
助记符:保持积极和前瞻性。
最后一次成功匹配中使用过的最晚关闭的组(即具有最右边的右括号的组)匹配的文本。 (参见 "正则表达式变量的作用域规则")。
这与 $+
有细微的差别。 例如在
"ab" =~ /^((.)(.))$/
我们有
$1,$^N have the value "ab"
$2 has the value "a"
$3,$+ have the value "b"
这主要用于 (?{...})
块中,用于检查最近匹配的文本。 例如,要有效地将文本捕获到变量(除了 $1
, $2
等),请将 (...)
替换为
(?:(...)(?{ $var = $^N }))
通过以这种方式设置和使用 $var
,您不必担心它们究竟是哪一组编号的括号。
此变量是只读的,其值是动态作用域的。
此变量是在 Perl v5.8.0 中添加的。
助记符:最晚关闭的(可能)嵌套括号。
此数组保存最后一次成功匹配的结束位置以及模式包含的任何匹配捕获缓冲区的偏移量。 (参见 "正则表达式变量的作用域规则")
它包含的元素数量将比模式中的捕获缓冲区数量多一个,无论哪些捕获缓冲区实际匹配。 您可以使用它来确定模式中存在多少个捕获缓冲区。 (与 @-
不同,它可能包含更少的元素。)
$+[0]
是整个匹配结束位置的字符串偏移量。 这与在调用匹配的变量时 pos
函数返回的值相同。 此数组的第 n 个元素保存第 n 个子匹配的偏移量,因此 $+[1]
是 $1
结束后的偏移量,$+[2]
是 $2
结束后的偏移量,依此类推。 您可以使用 $#+
来确定最后一次成功匹配中有多少个子组。 请参阅为 @-
变量给出的示例。
此变量是只读的,其值是动态作用域的。
此变量在 Perl v5.6.0 中添加。
类似于 @+
,%+
哈希允许访问命名的捕获缓冲区(如果存在),这些缓冲区位于当前活动动态作用域中最后一次成功的匹配中。(参见 "正则表达式变量的作用域规则")。
例如,$+{foo}
等效于以下匹配后的 $1
'foo' =~ /(?<foo>foo)/;
%+
哈希的键只列出已捕获(因此与定义的值相关联)的缓冲区的名称。
如果多个不同的捕获组具有相同的名称,则 $+{NAME}
将引用匹配中定义的最左侧的组。
%+
的底层行为由 Tie::Hash::NamedCapture 模块提供。
注意: %-
和 %+
是与最后一次成功的正则表达式关联的公共内部哈希的绑定视图。因此,通过 each
对它们进行迭代访问可能会产生不可预测的结果。同样,如果最后一次成功的匹配发生变化,则结果可能会令人惊讶。
此变量在 Perl v5.10.0 中添加。%{^CAPTURE}
别名在 5.25.7 中添加。
此变量是只读的,其值是动态作用域的。
此数组保存最后一次成功匹配及其包含的任何捕获缓冲区的开头的偏移量。(参见 "正则表达式变量的作用域规则")。
它包含的元素数量将比实际匹配到内容的最高捕获缓冲区(也称为子组)的数量多一个。(与 @+
不同,@+
可能包含更少的元素。)
$-[0]
是最后一次成功匹配的开头的偏移量。$-[n]
是由第 n 个子模式匹配的子字符串的开头的偏移量,如果子模式没有匹配,则为 undef。
因此,在与$_
匹配后,$&
与substr $_, $-[0], $+[0] - $-[0]
一致。类似地,如果$-[n]
已定义,则$n
与substr $_, $-[n], $+[n] - $-[n]
一致,而$+
与substr $_, $-[$#-], $+[$#-] - $-[$#-]
一致。可以使用$#-
查找上次成功匹配中最后一个匹配的子组。与$#+
形成对比,$#+
是正则表达式中子组的数量。
$-[0]
是整个匹配项在字符串中的偏移量。此数组的第n个元素保存第n个子匹配项的偏移量,因此$-[1]
是$1
开始的偏移量,$-[2]
是$2
开始的偏移量,依此类推。
在与某个变量$var
匹配后
$`
与substr($var, 0, $-[0])
相同$&
与substr($var, $-[0], $+[0] - $-[0])
相同$'
与substr($var, $+[0])
相同$1
与substr($var, $-[1], $+[1] - $-[1])
相同$2
与substr($var, $-[2], $+[2] - $-[2])
相同$3
与substr($var, $-[3], $+[3] - $-[3])
相同此变量是只读的,其值是动态作用域的。
此变量在 Perl v5.6.0 中添加。
类似于%+
,此变量允许访问当前活动动态作用域中上次成功匹配的命名捕获组。(参见"正则表达式变量的作用域规则")。对于在正则表达式中找到的每个捕获组名称,它都与一个对数组的引用相关联,该数组包含由所有具有该名称的缓冲区捕获的值列表(如果有几个),按照它们出现的顺序。
这是一个例子
if ('1234' =~ /(?<A>1)(?<B>2)(?<A>3)(?<B>4)/) {
foreach my $bufname (sort keys %-) {
my $ary = $-{$bufname};
foreach my $idx (0..$#$ary) {
print "\$-{$bufname}[$idx] : ",
(defined($ary->[$idx])
? "'$ary->[$idx]'"
: "undef"),
"\n";
}
}
}
将打印出
$-{A}[0] : '1'
$-{A}[1] : '3'
$-{B}[0] : '2'
$-{B}[1] : '4'
%-
哈希的键对应于在正则表达式中找到的所有缓冲区名称。
%-
的行为是通过 Tie::Hash::NamedCapture 模块实现的。
注意:%-
和 %+
是与最后一次成功的正则表达式关联的公共内部哈希的绑定视图。因此,通过 each
对它们进行迭代访问可能会产生不可预测的结果。同样,如果最后一次成功的匹配发生变化,则结果可能出乎意料。请参阅 "正则表达式变量的作用域规则"。
此变量是在 Perl v5.10.0 中添加的。%{^CAPTURE_ALL}
别名是在 5.25.7 中添加的。
此变量是只读的,其值是动态作用域的。
在当前作用域中最后一次成功匹配的模式。空模式默认匹配此模式。例如
if (m/foo/ || m/bar/) {
s//BLAH/;
}
和
if (m/foo/ || m/bar/) {
s/${^LAST_SUCCESSFUL_PATTERN}/BLAH/;
}
是等效的。
您可以使用它来调试最后匹配的模式,或再次使用它进行匹配。
在 Perl 5.37.10 中添加。
最后一次成功 (?{ code })
正则表达式断言(参见 perlre)的评估结果。
此变量可以写入,并且它的值是正常作用域的,与大多数其他正则表达式变量不同。
此变量是在 Perl 5.005 中添加的。
当前值,表示在正则表达式编译期间任何时候可能存在的未关闭的圆括号组的最大数量。默认值为 1000 个嵌套组。您可以根据您的需要和可用内存量进行调整。
此变量是在 Perl v5.30.0 中添加的。
正则表达式调试标志的当前值。设置为 0 表示即使加载了 re 'debug'
模块,也不输出调试信息。有关详细信息,请参阅 re。
此变量在 Perl v5.10.0 中添加。
控制如何应用某些正则表达式优化以及它们使用多少内存。此值的默认值为 65536,对应于 512kB 的临时缓存。将此值设置为更高的值,以便在匹配大型交替时用内存换取速度。如果希望优化尽可能节省内存,但仍然发生,则将其设置为较低的值,如果要防止优化并尽可能节省内存,则将其设置为负值。在正常情况下,您应该对这个变量不感兴趣。
此变量在 Perl v5.10.0 中添加。
依赖于当前选定文件句柄的变量可以通过调用 IO::Handle
对象上的适当对象方法来设置,尽管这比使用常规内置变量效率低。(下面关于此的摘要行包含单词 HANDLE。)首先,您必须说
use IO::Handle;
之后您可以使用以下任一方法
method HANDLE EXPR
或者更安全地,
HANDLE->method(EXPR)
每个方法都返回 IO::Handle
属性的旧值。每个方法都接受一个可选的 EXPR,如果提供,则指定 IO::Handle
属性的新的值。如果没有提供,大多数方法不会对当前值进行任何操作,除了 autoflush()
,它会为您假设为 1,只是为了与众不同。
由于加载 IO::Handle
类是一个昂贵的操作,您应该学习如何使用常规内置变量。
其中一些变量被认为是“只读”的。这意味着如果您尝试直接或间接通过引用分配给此变量,您将引发运行时异常。
在修改本文档中描述的大多数特殊变量的默认值时,您应该非常小心。在大多数情况下,您希望在更改这些变量之前将它们本地化,因为如果您不这样做,更改可能会影响依赖于您已更改的特殊变量的默认值的其它模块。这是读取整个文件一次的正确方法之一
open my $fh, "<", "foo" or die $!;
local $/; # enable localized slurp mode
my $content = <$fh>;
close $fh;
但是以下代码很糟糕
open my $fh, "<", "foo" or die $!;
undef $/; # enable slurp mode
my $content = <$fh>;
close $fh;
因为某些其他模块可能希望从默认的“行模式”下读取某些文件中的数据,因此,如果我们刚刚呈现的代码已执行,$/
的全局值现在将更改为在同一 Perl 解释器中运行的任何其他代码。
通常,当一个变量被本地化时,您希望确保此更改影响尽可能小的范围。因此,除非您已经处于某个简短的 {}
块中,否则您应该自己创建一个。例如
my $content = '';
open my $fh, "<", "foo" or die $!;
{
local $/;
$content = <$fh>;
}
close $fh;
以下是如何使您自己的代码崩溃的示例
for ( 1..3 ){
$\ = "\r\n";
nasty_break();
print "$_";
}
sub nasty_break {
$\ = "\f";
# do something with $_
}
您可能希望此代码打印等效于
"1\r\n2\r\n3\r\n"
但您得到的是
"1\f2\f3\f"
为什么?因为 nasty_break()
修改了 $\
而不先将其本地化。您在 nasty_break()
中设置的值在您返回时仍然存在。解决方法是添加 local()
,这样值就不会泄漏到 nasty_break()
之外
local $\ = "\f";
在如此简短的示例中很容易注意到问题,但在更复杂的代码中,如果您不将对特殊变量的更改本地化,您就是在寻找麻烦。
从<>
读取时,包含当前文件的名称。
数组@ARGV
包含脚本的命令行参数。$#ARGV
通常是参数数量减一,因为$ARGV[0]
是第一个参数,而不是程序本身的命令名称。有关命令名称,请参见"$0"。
特殊文件句柄,它在@ARGV
中迭代命令行文件名。通常在角度运算符<>
中写为空文件句柄。请注意,目前ARGV
仅在<>
运算符中具有其神奇效果;在其他地方,它只是一个普通的文件句柄,对应于<>
最后打开的文件。特别是,将\*ARGV
作为参数传递给期望文件句柄的函数可能不会导致您的函数自动读取@ARGV
中所有文件的内容。
特殊文件句柄,它指向使用-i进行就地编辑时当前打开的输出文件。当您需要进行大量插入并且不想不断修改$_
时很有用。有关-i开关,请参见perlrun。
print 运算符的输出字段分隔符。如果已定义,此值将打印在 print 的每个参数之间。默认值为undef
。
您不能在句柄上调用output_field_separator()
,只能作为静态方法调用。参见IO::Handle。
助记符:在您的 print 语句中出现 "," 时打印的内容。
访问的最后一个文件句柄的当前行号。
Perl 中的每个文件句柄都会统计从该句柄中读取的行数。(根据 $/
的值,Perl 对行的定义可能与你的定义不一致。)当从文件句柄中读取一行(通过 readline()
或 <>
),或者当对该句柄调用 tell()
或 seek()
时,$.
将成为该文件句柄的行计数器的别名。
你可以通过赋值给 $.
来调整计数器,但这不会实际移动查找指针。局部化 $.
不会局部化文件句柄的行计数。相反,它会局部化 Perl 对 $.
当前别名指向的文件句柄的认识。
当文件句柄关闭时,$.
会被重置,但不会在打开的文件句柄在没有进行 close()
的情况下重新打开时重置。有关更多详细信息,请参阅 "perlop 中的 I/O 运算符"。由于 <>
从不进行显式关闭,因此行号会跨 ARGV
文件递增(但请参阅 "perlfunc 中的 eof" 中的示例)。
你也可以使用 HANDLE->input_line_number(EXPR)
来访问给定文件句柄的行计数器,而无需担心你最后访问的是哪个句柄。
助记符:许多程序使用 "." 来表示当前行号。
输入记录分隔符,默认情况下为换行符。这会影响 Perl 对“行”的理解。与 awk 的 RS 变量的工作方式相同,包括在设置为空字符串时将空行视为终止符(空行不能包含任何空格或制表符)。你可以将其设置为多字符字符串以匹配多字符终止符,或设置为 undef
以读取到文件末尾。将其设置为 "\n\n"
与设置为 ""
的含义略有不同,如果文件包含连续的空行。设置为 ""
将把两个或多个连续的空行视为一个空行。设置为 "\n\n"
将盲目地假设下一个输入字符属于下一段,即使它是一个换行符。
local $/; # enable "slurp" mode
local $_ = <FH>; # whole file now here
s/\n[ \t]+/ /g;
请记住:$/
的值是一个字符串,而不是一个正则表达式。awk 在某些方面必须比它更好。:-)
将 $/
设置为空字符串——所谓的段落模式——值得特别注意。当 $/
设置为 ""
并且整个文件在该设置下被读取时,文件开头的任何一个或多个连续换行符序列都会被丢弃。除了文件中的最后一个记录外,每个以两个或多个换行符结尾的字符序列都被视为一个记录,并被读取为以两个换行符结尾。如果文件中的最后一个记录以零个或一个连续的换行符结尾,则该记录将以该数量的换行符被读取。如果最后一个记录以两个或多个连续的换行符结尾,则它将像所有前面的记录一样以两个换行符被读取。
假设我们向文件写入以下字符串
my $string = "\n\n\n";
$string .= "alpha beta\ngamma delta\n\n\n";
$string .= "epsilon zeta eta\n\n";
$string .= "theta\n";
my $file = 'simple_file.txt';
open my $OUT, '>', $file or die;
print $OUT $string;
close $OUT or die;
现在我们以段落模式读取该文件
local $/ = ""; # paragraph mode
open my $IN, '<', $file or die;
my @records = <$IN>;
close $IN or die;
@records
将包含这 3 个字符串
(
"alpha beta\ngamma delta\n\n",
"epsilon zeta eta\n\n",
"theta\n",
)
将 $/
设置为对整数、包含整数的标量或可转换为整数的标量的引用,将尝试读取记录而不是行,最大记录大小为引用的整数字符数。所以这个
local $/ = \32768; # or \"32768", or \$var_containing_32768
open my $fh, "<", $myfile or die $!;
local $_ = <$fh>;
将从 $fh 读取不超过 32768 个字符的记录。如果您没有从面向记录的文件中读取(或者您的操作系统没有面向记录的文件),那么您可能会在每次读取时获得一整块数据。如果记录大于您设置的记录大小,您将分段获得记录。尝试将记录大小设置为零或更小已弃用,并将导致 $/
的值为“undef”,这将导致读取整个文件(的剩余部分)。
从 5.19.9 开始,将 $/
设置为任何其他形式的引用将抛出致命异常。这是为了准备将来支持设置 $/
的新方法。
仅在 VMS 上,记录读取会绕过 PerlIO 层和任何相关的缓冲,因此您不得在同一个文件句柄上混合记录读取和非记录读取。当同一缓冲层用于两种模式时,记录模式仅与行模式混合。
您不能在句柄上调用 input_record_separator()
,只能作为静态方法调用。请参阅 IO::Handle。
另请参阅 "perlport 中的新行"。另请参阅 "$."。
助记符:/ 在引用诗歌时分隔行边界。
print 运算符的输出记录分隔符。如果已定义,则此值将在 print 的最后一个参数之后打印。默认值为 undef
。
您不能在句柄上调用 output_record_separator()
,只能作为静态方法调用。请参阅 IO::Handle。
助记符:您设置 $\
而不是在 print 的末尾添加 "\n"。此外,它就像 $/
一样,但它是您从 Perl 获得的“返回”值。
如果设置为非零值,则强制立即刷新,并在当前选定的输出通道上每次写入或打印后刷新。默认值为 0(无论通道是否真的被系统缓冲;$|
仅告诉您是否已明确要求 Perl 在每次写入后刷新)。如果输出到终端,STDOUT 通常会进行行缓冲,否则会进行块缓冲。设置此变量主要在您输出到管道或套接字时有用,例如,当您在rsh下运行 Perl 程序并希望在输出发生时看到输出时。这不会影响输入缓冲。有关详细信息,请参阅 "perlfunc 中的 getc"。有关如何选择输出通道的信息,请参阅 "perlfunc 中的 select"。另请参阅 IO::Handle。
助记符:当您希望您的管道热气腾腾时。
此只读变量包含对最后读取的文件句柄的引用。它由 <HANDLE>
、readline
、tell
、eof
和 seek
设置。这是与 $.
、tell
和 eof
(不带参数)使用相同的句柄。它也是 Perl 在错误或警告消息中附加 ", <STDIN> line 1" 时使用的句柄。
此变量是在 Perl v5.18.0 中添加的。
格式的特殊变量是文件句柄特殊变量的子集。有关 Perl 格式的更多信息,请参阅 perlform。
format()
行的 write()
累加器的当前值。格式包含 formline()
调用,这些调用将其结果放入 $^A
中。在调用其格式后,write()
会打印出 $^A
的内容并清空。因此,除非您自己调用 formline()
然后查看它,否则您永远不会真正看到 $^A
的内容。请参阅 perlform 和 "perlfunc 中的 formline PICTURE,LIST"。
哪些格式输出为换页符?默认值为\f
。
您不能在句柄上调用format_formfeed()
,只能作为静态方法调用。请参阅IO::Handle。
当前选定输出通道的当前页码。
助记符:%
是 nroff 中的页码。
当前选定输出通道的页面上剩余的行数。
助记符:lines_on_page - lines_printed。
当前字符集,在这些字符之后,字符串可以被拆分以填充格式中的延续字段(以^
开头)。默认值为" \n-",在空格、换行符或连字符处断开。
您不能在句柄上调用format_line_break_characters()
,只能作为静态方法调用。请参阅IO::Handle。
助记符:诗歌中的“冒号”是行的一部分。
当前选定输出通道的当前页长(可打印行数)。默认值为 60。
助记符:= 有水平线。
当前选定输出通道的当前页眉格式的名称。默认值为文件句柄的名称,附加_TOP
。例如,STDOUT
文件句柄的默认页眉格式名称为STDOUT_TOP
。
助记符:指向页面顶部。
当前所选输出通道的当前报表格式名称。默认格式名称与文件句柄名称相同。例如,STDOUT
文件句柄的默认格式名称就是 STDOUT
。
助记符:$^
的兄弟。
变量 $@
、$!
、$^E
和 $?
包含有关 Perl 程序执行过程中可能出现的不同类型的错误条件的信息。这些变量按报告错误的子系统与 Perl 进程之间的“距离”排序。它们分别对应于 Perl 解释器、C 库、操作系统或外部程序检测到的错误。
为了说明这些变量之间的区别,请考虑以下 Perl 表达式,它使用单引号字符串。在执行此语句后,perl 可能已设置了所有四个特殊的错误变量
eval q{
open my $pipe, "/cdrom/install |" or die $!;
my @res = <$pipe>;
close $pipe or die "bad pipe: $?, $!";
};
当 perl 执行 eval()
表达式时,它会将 open()
、<PIPE>
和 close
调用转换为 C 运行时库,然后转换为操作系统内核。如果其中一个调用失败,perl 会将 $!
设置为 C 库的 errno
。
如果要 eval
的字符串未编译(如果 open
或 close
使用错误的原型导入,或者如果在评估期间执行的 Perl 代码 die()
d,则会设置 $@
。在这些情况下,$@
的值为编译错误,或 die
的参数(它将插入 $!
和 $?
)。(另请参阅 致命错误。)
在少数操作系统下,$^E
可能包含更详细的错误指示器,例如在这种情况下,“CDROM 托盘未关闭”。不支持扩展错误消息的系统会将 $^E
保持与 $!
相同。
最后,如果外部程序 /cdrom/install 失败,则 $?
可能被设置为非 0 值。高八位反映程序遇到的特定错误条件(程序的 exit()
值)。低八位反映失败模式,例如信号死亡和核心转储信息。有关详细信息,请参阅 wait(2)。与仅在检测到错误条件时才设置的 $!
和 $^E
相反,变量 $?
在每次 wait
或管道 close
时都会被设置,覆盖旧值。这更像是 $@
,它在每次 eval()
时都会在失败时被设置,并在成功时被清除。
有关更多详细信息,请参阅 $@
、$!
、$^E
和 $?
中的各个说明。
由最后一个管道关闭、反引号 (``
) 命令、对 wait()
或 waitpid()
的成功调用,或由 system()
运算符返回的原生状态。在类 POSIX 的系统上,此值可以使用 POSIX 模块提供的 WIFEXITED、WEXITSTATUS、WIFSIGNALED、WTERMSIG、WIFSTOPPED 和 WSTOPSIG 函数解码。
在 VMS 下,这反映了实际的 VMS 退出状态;即,当使用 use vmsish 'status'
编译指示时,它与 $?
相同。
此变量在 Perl v5.10.0 中添加。
特定于当前操作系统的错误信息。目前,这仅在 VMS、OS/2 和 Win32(以及 MacPerl)下与 "$!"
不同。在所有其他平台上,$^E
始终与 $!
相同。
在 VMS 下,$^E
提供来自最后一个系统错误的 VMS 状态值。这比 $!
提供的关于最后一个系统错误的更具体的信息。当 $!
设置为 EVMSERR 时,这尤其重要。
在 OS/2 下,$^E
设置为通过 CRT 或直接从 perl 调用 OS/2 API 的最后一个调用的错误代码。
在 Win32 下,$^E
始终返回由 Win32 调用 GetLastError()
报告的最后一个错误信息,该信息描述了 Win32 API 中的最后一个错误。大多数特定于 Win32 的代码将通过 $^E
报告错误。ANSI C 和类 Unix 调用设置 errno
,因此大多数可移植的 Perl 代码将通过 $!
报告错误。
"$!"
描述中提到的注意事项通常也适用于 $^E
。
此变量是在 Perl 5.003 中添加的。
助记符:额外的错误解释。
解释器的当前状态。
$^S State
--------- -------------------------------------
undef Parsing module, eval, or main program
true (1) Executing an eval or try block
false (0) Otherwise
第一个状态可能发生在 $SIG{__DIE__}
和 $SIG{__WARN__}
处理程序中。
英文名称 $EXCEPTIONS_BEING_CAUGHT 有点误导,因为 undef
值不表示是否正在捕获异常,因为主程序的编译不会捕获异常。
此变量是在 Perl 5.004 中添加的。
警告开关的当前值,如果使用了 -w,则最初为真,否则为假,但可以直接修改。
另请参见 warnings。
助记符:与 -w 开关相关。
由 use warnings
编译指示启用的当前警告检查集。它具有与 $^H
和 %^H
变量相同的范围。确切的值被认为是 warnings 编译指示的内部值,并且可能在 Perl 的不同版本之间发生变化。
每次语句编译完成后,都会将${^WARNING_BITS}
的当前值与该语句一起存储,之后可以通过(caller($level))[9]
检索。
此变量在 Perl v5.6.0 中添加。
当引用时,$!
检索C语言errno
整数变量的当前值。如果$!
被赋值为数值,则该值将存储在errno
中。当引用为字符串时,$!
会生成与errno
对应的系统错误字符串。
许多系统或库调用在失败时会设置errno
,以指示失败原因。它们通常在成功时不会将errno
设置为零,并且可能在成功时将errno
设置为非零值。这意味着errno
,因此$!
,只有在失败之后才有意义。
if (open my $fh, "<", $filename) {
# Here $! is meaningless.
...
}
else {
# ONLY here is $! meaningful.
...
# Already here $! might be meaningless.
}
# Since here we might have either success or failure,
# $! is meaningless.
这里,无意义意味着$!
可能与open()
操作的结果无关。对$!
的赋值同样是短暂的。它可以在调用die()
操作符之前立即使用,以设置退出值,或检查与错误n对应的系统错误字符串,或将$!
恢复到有意义的状态。
即使没有执行系统调用,Perl本身也可能在失败时将errno
设置为非零值。
助记符:刚刚发生了什么?
%!
的每个元素只有在$!
被设置为该值时才具有真值。例如,$!{ENOENT}
为真当且仅当$!
的当前值为ENOENT
;也就是说,如果最近的错误是“没有这样的文件或目录”(或其道德等价物:并非所有操作系统都给出该确切的错误,当然并非所有语言都给出该确切的错误)。具体的真值没有保证,但在过去通常是$!
的数值。要检查特定键在您的系统上是否有意义,请使用exists $!{the_key}
;要获取合法键的列表,请使用keys %!
。有关更多信息,请参见Errno,另请参见"$!"。
此变量是在 Perl 5.005 中添加的。
由最后一个管道关闭、反引号(``
)命令、对wait()
或waitpid()
的成功调用或system()
操作符返回的状态。这只是传统 Unix wait()
系统调用返回的 16 位状态字(或者被制作成看起来像它)。因此,子进程的退出值实际上是($? >> 8
),而$? & 127
给出进程因何信号而死(如果有),而$? & 128
报告是否发生了核心转储。
此外,如果 C 中支持h_errno
变量,则如果任何gethost*()
函数失败,其值将通过$?
返回。
如果您为SIGCHLD
安装了信号处理程序,则$?
的值通常在该处理程序之外是错误的。
在 END
子例程中,$?
包含将传递给 exit()
的值。您可以在 END
子例程中修改 $?
以更改程序的退出状态。例如
END {
$? = 1 if $? == 255; # die would make it 255
}
在 VMS 下,pragma use vmsish 'status'
使 $?
反映实际的 VMS 退出状态,而不是 POSIX 状态的默认模拟;有关详细信息,请参阅 "$?" in perlvms。
助记符:类似于 sh 和 ksh。
来自最后一个 eval
运算符的 Perl 错误,即最后一个被捕获的异常。对于 eval BLOCK
,这要么是运行时错误消息,要么是字符串或引用 die
被调用的内容。eval STRING
形式还会捕获语法错误和其他编译时异常。
如果未发生错误,eval
将 $@
设置为空字符串。
警告消息不会收集到此变量中。但是,您可以通过设置 $SIG{__WARN__}
来设置一个处理警告的例程,如 "%SIG" 中所述。
助记符:错误发生在“哪里”?
这些变量提供有关当前解释器状态的信息。
与 -c 开关关联的标志的当前值。主要用于 -MO=...,以允许代码在编译时更改其行为,例如,例如在编译时进行 AUTOLOAD
而不是正常的延迟加载。设置 $^C = 1
与调用 B::minus_c
相似。
此变量在 Perl v5.6.0 中添加。
调试标志的当前值。可以读取或设置。与它的 命令行等效项 一样,您可以使用数字或符号值,例如 $^D = 10
或 $^D = "st"
。请参阅 "-Dnumber" in perlrun。此变量的内容也会影响调试器操作。请参阅 "Debugger Internals" in perldebguts。
助记符:-D 开关的值。
Perl 解释器的当前阶段。
可能的值是
PerlInterpreter*
通过 perl_construct
进行构建。此值主要用于完整性和通过底层 C 变量 PL_phase
使用。在解释器构建完成之前,Perl 代码实际上无法执行。
这是全局编译时。基本上包括在顶层程序的编译时直接或间接执行的每个 BEGIN
块。
此阶段不称为“BEGIN”,以避免与 BEGIN
块混淆,因为这些块在任何编译单元的编译时执行,而不仅仅是顶层程序。在运行时进入新的本地化编译时,例如通过 eval "use SomeModule"
等结构,不是全局解释器阶段,因此不会反映在 ${^GLOBAL_PHASE}
中。
执行任何 CHECK
块。
类似于“CHECK”,但针对 INIT
块,而不是 CHECK
块。
主运行时,即 PL_main_root
的执行。
执行任何 END
块。
全局销毁。
还要注意,没有 UNITCHECK 块的值。这是因为它们是针对每个编译单元单独运行的,因此不是全局解释器阶段。
并非每个程序都必须经过所有可能的阶段,但从一个阶段过渡到另一个阶段只能按照上述列表中描述的顺序进行。
Perl 代码可以看到的所有阶段的示例
BEGIN { print "compile-time: ${^GLOBAL_PHASE}\n" }
INIT { print "init-time: ${^GLOBAL_PHASE}\n" }
CHECK { print "check-time: ${^GLOBAL_PHASE}\n" }
{
package Print::Phase;
sub new {
my ($class, $time) = @_;
return bless \$time, $class;
}
sub DESTROY {
my $self = shift;
print "$$self: ${^GLOBAL_PHASE}\n";
}
}
print "run-time: ${^GLOBAL_PHASE}\n";
my $runtime = Print::Phase->new(
"lexical variables are garbage collected before END"
);
END { print "end-time: ${^GLOBAL_PHASE}\n" }
our $destruct = Print::Phase->new(
"package variables are garbage collected after END"
);
这将打印出
compile-time: START
check-time: CHECK
init-time: INIT
run-time: RUN
lexical variables are garbage collected before END: RUN
end-time: END
package variables are garbage collected after END: DESTRUCT
此变量是在 Perl 5.14.0 中添加的。
警告:此变量严格用于内部使用。其可用性、行为和内容可能会在未经通知的情况下发生更改。
此变量包含 Perl 解释器的编译时提示。在 BLOCK 编译结束时,此变量的值将恢复为解释器开始编译 BLOCK 时的值。
每次语句完成编译时,$^H
的当前值都会与该语句一起存储,并且以后可以通过 (caller($level))[8]
检索。请参阅 "caller EXPR" in perlfunc。
当 perl 开始解析任何提供词法范围的块结构(例如,eval 体、所需文件、子例程体、循环体或条件块)时,会保存 $^H
的现有值,但其值保持不变。当块的编译完成时,它将恢复保存的值。在保存和恢复其值之间,在 BEGIN 块中执行的代码可以自由更改 $^H
的值。
此行为提供了词法范围的语义,并用于例如 use strict
编译指示。
内容应该是一个整数;它的不同位用于不同的语义标志。以下是一个例子
sub add_100 { $^H |= 0x100 }
sub foo {
BEGIN { add_100() }
bar->baz($boon);
}
考虑在执行 BEGIN 块期间会发生什么。此时 BEGIN 块已经编译完成,但 foo()
的主体仍在编译中。因此,$^H
的新值只在编译 foo()
的主体时可见。
用以下内容替换 BEGIN { add_100() }
块
BEGIN { require strict; strict->import('vars') }
演示了 use strict 'vars'
的实现方式。以下是一个相同词法语法的条件版本
BEGIN {
require strict; strict->import('vars') if $condition
}
此变量是在 Perl 5.003 中添加的。
%^H
哈希提供了与 $^H
相同的范围语义。这使得它对于实现词法范围的语法非常有用。参见 perlpragma。所有条目在运行时被字符串化,因此只能容纳简单值。这意味着例如不能引用对象。
每次语句完成编译时,%^H
的当前值都会与该语句一起存储,并且之后可以通过 (caller($level))[10]
检索。参见 "caller EXPR" in perlfunc.
将项目放入 %^H
时,为了避免与哈希的其他用户发生冲突,关于使用哪些键存在一个约定。模块应该只使用以模块名称(其主包的名称)和 "/" 字符开头的键。例如,模块 Foo::Bar
应该使用诸如 Foo::Bar/baz
之类的键。
此变量在 Perl v5.6.0 中添加。
由 PerlIO 使用的内部变量。一个由 \0
字节分隔的两个部分的字符串,第一部分描述输入层,第二部分描述输出层。
这是应用 open 语法的词法效果以及 -C 命令行开关 和 PERL_UNICODE 环境变量 的 io
或 D
选项的主程序范围效果的机制。
函数 accept()
、open()
、pipe()
、readpipe()
(以及相关的 qx
和 `STRING`
运算符)、socket()
、socketpair()
和 sysopen()
受此变量的词法值影响。由 readline()
(或相关的 <>
和 <<>>
运算符)在传递的文件名上打开的隐式 "ARGV" 处理程序也会受到影响(但如果它打开 STDIN
则不会)。如果此变量未设置,这些函数将设置默认层,如 "Defaults and how to override them" in PerlIO 中所述。
当使用 3 个参数调用并指定显式层时,open()
会忽略此变量(以及默认层)。通过诸如 IO::Handle 之类的模块对这些函数的间接调用不受影响,因为它们发生在不同的词法范围内。由 opendir()
打开的目录句柄目前不受影响。
此变量是在 Perl v5.8.0 中添加的。
用于调试支持的内部变量。各个位的含义可能会发生变化,但目前表示
调试子程序进入/退出。
逐行调试。导致 DB::DB()
子程序在执行每个语句时被调用。还会导致保存源代码行(如 0x400)。
关闭优化。
为将来的交互式检查保留更多数据。
保留有关定义子程序的源代码行的信息。
从单步执行开始。
在报告时使用子程序地址而不是名称。
也报告 goto &subroutine
。
为基于编译位置的 evals 提供信息丰富的“文件”名。
为基于编译位置的匿名子程序提供信息丰富的名称。
将源代码行保存到 @{"_<$filename"}
中。
保存源代码时,包括不生成子程序的 evals。
保存源代码时,包括未编译的源代码。
某些位可能仅在编译时相关,某些位仅在运行时相关。这是一种新机制,细节可能会发生变化。另请参见 perldebguts。
反映污染模式是否开启。1 表示开启(程序使用 -T 运行),0 表示关闭,-1 表示仅启用污染警告(即使用 -t 或 -TU)。
注意:如果您的 perl 在没有污染支持的情况下构建(参见 perlsec),那么 ${^TAINT}
将始终为 0,即使程序使用 -T 运行。
此变量是只读的。
此变量是在 Perl v5.8.0 中添加的。
该变量反映了当前 Perl 是否支持安全区域设置操作(值为 1)或不支持(值为 0)。如果 Perl 在编译时没有使用线程,则该变量始终为 1。如果 Perl 使用线程安全的区域设置操作,则该变量也为 1。请注意,单个线程可以通过调用 "perlapi 中的 switch_to_global_locale" 来选择使用全局区域设置(通常不安全)。目前,此变量在这些线程中仍然设置为 1。
此变量是只读的。
该变量在 Perl v5.28.0 中添加。
该变量反映了 Perl 的某些 Unicode 设置。有关可能值的更多信息,请参阅 perlrun 文档中的 -C
选项。
该变量在 Perl 启动时设置,之后为只读。
该变量在 Perl v5.8.2 中添加。
该变量控制内部 UTF-8 偏移缓存代码的状态。1 表示开启(默认值),0 表示关闭,-1 表示通过将所有结果与线性扫描进行比较来调试缓存代码,并在出现任何差异时引发恐慌。
该变量在 Perl v5.8.9 中添加。它可能会在未经通知的情况下更改或删除,但目前用于避免重新计算多字节 UTF-8 编码字符的边界。
该变量指示 Perl 在启动时是否检测到 UTF-8 区域设置。当 Perl 处于调整 UTF-8 属性以匹配区域设置模式时(例如,在使用 -CL
命令行选项运行时),Perl 会使用此信息;有关此模式的更多信息,请参阅 perlrun。
该变量在 Perl v5.8.8 中添加。
弃用变量表示 Perl 维护人员打算最终从语言中删除该变量。尽管已弃用,但它可能仍然可用。使用已弃用的变量会触发警告。
一旦变量被删除,使用它会触发错误,告知你该变量不受支持。
有关错误消息的详细信息,请参阅 perldiag。
$#
是一个可以用来格式化打印数字的变量。经过弃用周期后,它的魔法在 Perl v5.10.0 中被删除,现在使用它会触发警告:$# is no longer supported
。
这不是你在数组名称前面使用的符号,用来获取最后一个索引,例如 $#array
。这仍然是你在 Perl 中获取数组最后一个索引的方式。这两者之间没有任何关系。
在 Perl 5 中已弃用。
在 Perl v5.10.0 中移除。
$*
是一个变量,您可以使用它来启用多行匹配。经过弃用周期后,它的魔法在 Perl v5.10.0 中被移除。现在使用它会触发警告:$* is no longer supported
。您应该使用 /s
和 /m
正则表达式修饰符代替。
在 Perl 5 中已弃用。
在 Perl v5.10.0 中移除。
此变量存储数组中第一个元素的索引,以及子字符串中第一个字符的索引。默认值为 0,但理论上您可以将其设置为 1,以使 Perl 在下标和评估 index() 和 substr() 函数时更像 awk(或 Fortran)。
从 Perl 第 5 版开始,对 $[
的赋值被视为编译器指令,不能影响任何其他文件的行为。(这就是为什么您只能将编译时常量分配给它的原因。)强烈建议不要使用它。
在 Perl v5.10.0 之前,对 $[
的赋值可以在同一个文件中的外部词法作用域中看到,这与其他编译时指令(如 strict)不同。在它上面使用 local() 将严格地将它的值绑定到词法块。现在它始终是词法作用域的。
从 Perl v5.16.0 开始,它由 arybase 模块实现。
从 Perl v5.30.0 开始,或在 use v5.16
或 no feature "array_base"
下,$[
不再有任何作用,并且始终包含 0。允许将 0 分配给它,但任何其他值都会产生错误。
助记符:[ 开始下标。
在 Perl v5.12.0 中已弃用。
此变量不再受支持。
它曾经保存用于将源代码转换为 Unicode 的 Encode
对象的对象引用。
它的目的是允许您的非 ASCII Perl 脚本不必用 UTF-8 编写;这在使用 UTF-8 编码文本的编辑器很常见之前很有用,但那已经是很久以前的事了。它会导致问题,例如影响其他模块的操作,而这些模块没有预期它,从而导致普遍混乱。
如果您需要类似的功能,建议您使用一个简单的源代码过滤器,例如 Filter::Encoding。
如果您是因为您的代码受到他人使用此变量的负面影响而来到这里,您通常可以通过以下方法解决:
local ${^ENCODING};
在被破坏的函数的开头附近。这会在包含函数的执行范围内取消定义该变量。
此变量是在 Perl 5.8.2 中添加的,并在 5.26.0 中删除。在 Perl 5.28.0 中,将其设置为除 undef
之外的任何值都会导致致命错误。
此变量不再有任何功能。
此变量是在 Perl v5.10.0 中添加的,并在 Perl v5.34.0 中删除。