分类:
2007-11-02 16:57:07
NAME
perlvar - Perl 预定义变量
DESCRIPTION
预定义名称
后面列出的名称对 Perl 来说具有特殊含义。
大多数标点名称都有合理的助记方法或类似于在 shell 中的用法。
然而,如果你就是想用长变量名,那只要在程序开头加上
use English;
即可。这样会为所有短名称在当前包中创建长名称别名。
其中一些甚至还有中间名,一般是从 awk 借用过来的。 一般来说,如果不需要
$PREMATCH,$MATCH 和 $POSTMATCH,那最好使用
use English '-no_match_vars';
调用方式,因为它能避免在用正则表达式时出现效率降低的情况。见 English。
依赖当前被选中文件句柄的变量可以通过在 IO::Handle
对象上调用合适的对象方法来设置,
但是这要比使用普通的内建变量效率低一些。(下面的概括行里包含的单词 HANDLE
即指 IO::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..5){
nasty_break();
print "$_ ";
}
sub nasty_break {
$_ = 5;
# do something with $_
}
你可能希望上述代码打印出:
1 2 3 4 5
但实际上得到的却是:
5 5 5 5 5
为什么?因为 nasty_break() 修改了 $_ 而没有事先将其局部化。
改正方法是增加 local():
local $_ = 5;
虽然在这样一个短小的例子里很容易发现问题,但在更复杂的代码中,如果不
对特殊变量进行局部化更改就是在自找麻烦。
下列内容按照先标量变量、后数组、最后散列的顺序排列。
$ARG
$_ 默认的输入和模式搜索空间。下面的几对代码都是等同的:
while (<>) {...} # equivalent only in while!
while (defined($_ = <>)) {...}
/^Subject:/
$_ =~ /^Subject:/
tr/a-z/A-Z/
$_ =~ tr/a-z/A-Z/
chomp
chomp($_)
以下是几处即使没有写明 Perl 也会假定使用 $_ 的地方:
* 各种单目函数,包括像 ord() 和 int() 这样的函数以及除 "-t"
以外所有的文件 测试操作 ("-f","-d"),"-t" 默认操作 STDIN。
* 各种列表函数,例如 print() 和 unlink()。
* 没有使用 "=~" 运算符时的模式匹配操作 "m//"、"s///" 和
"tr///"。
* 在没有给出其他变量时是 "foreach" 循环的默认迭代变量。
* grep() 和 map() 函数的隐含迭代变量。
* 当 "while" 仅有唯一条件,且该条件是对 ""
操作的结果进行测试时,$_ 就是存放输入记录的默认位置。除了
"while" 测试条件之外不会发生这种情况。
(助记:下划线在特定操作中是可以省略的。)
$a
$b 是使用 sort() 时的特殊包变量,参见 "sort" in perlfunc。
由于这一特殊性,$a 和 $b 即使在用了 "strict 'vars'"
指示符以后也不需要声明(用 use vars 或者 our())。 如果想要在
sort() 的比较块或者函数中使用它们,就不要用 "my $a" 或 "my $b"
将其词法化。
$<*digits*>
含有上次模式匹配中捕获括号集合所对应的子模式,不包括已经退出的嵌
套 块中匹配的模式。(助记:类似 \digits。)
这些变量全都是只读的,对于 当前块来说具有动态作用域。
$MATCH
$& 含有上次成功的模式匹配所匹配到的字符串(不包括任何隐藏在块中的匹?
浠虻鼻?块所包围的 eval())。(助记:同一些编辑器中的 & 类似。)
该变量是只读的, 对于当前块来说具有动态作用域。
在程序中任何地方使用该变量都会使所有正则表达式匹配产生可观的效率
降低。 参见 "BUGS"。
$PREMATCH
$` 含有上次成功的模式匹配内容之前的字符串(不包括任何隐藏在块中的匹?
浠虻鼻?块所包围的 eval)。(助记:"`"
常常出现在引起的字符串之前。) 该变量是只读的。
在程序中任何地方使用该变量都会使所有正则表达式匹配产生可观的效率
降低。 参见 "BUGS"。
$POSTMATCH
$' 含有上次成功的模式匹配内容之后的字符串(不包括任何隐藏在块中的匹?
浠虻鼻?块所包围的 eval())。(助记:"'"
常常跟在引起的字符串之后。) 例如:
local $_ = 'abcdefghi';
/def/;
print "$`:$&:$'\n"; # prints abc:def:ghi
该变量只读且对于当前块具有动态作用域。
在程序中任何地方使用该变量都会使所有正则表达式匹配产生可观的效率
降低。 参见 "BUGS"。
$LAST_PAREN_MATCH
$+ 含有上次成功的搜索模式中最后一个括号匹配的文本。在无法知道可选模
式集中 到底哪一个匹配成功时,该变量是非常有用的。例如:
/Version: (.*)|Revision: (.*)/ && ($rev = $+);
(助记:积极一点儿向前看。)(译注:“积极”与“正号”是同一个单词?
? 该变量只读且相对于当前块具有动态作用域。
$^N 含有上一次成功搜索模式中最近闭合的组(即最右边的右括号构成的组)所
匹配 的文本。(助记:最近闭合的(可能)嵌套的括号。)
(译注:嵌套的单词为 Nest。)
该变量主要用在 "(?{...})"
块的内部,以便检查最近匹配到的文本。例如,
为了有效地用一个变量($1、$2 等等之外的变量)捕获文本,可以将
"(...)" 替换为
(?:(...)(?{ $var = $^N }))
像这样设置并使用 $var 就能把你从计算括号个数的烦恼中解放出来了。
该变量对于当前块具有动态作用域。
@LAST_MATCH_END
@+ 该数组保存了当前活动的动态作用域中最近成功的子匹配结束处的偏移量
。 $+[0]
为整个匹配在字符串中结束处的偏移量,这同用被匹配的变量调用 "pos"
函数得到的值一样。该数组的第 *n* 个元素保存了第 *n* 个子匹配
的偏移量,因此 $+[1] 就是紧接着 $1 结束处的偏移量,$+[2] 是
紧接着 $2 结束处的偏移量,以此类推。可以用 $#+
得知最近成功的匹配 中有多少个组。参见为 "@-" 变量给出的例子。
$* 将其设为非零整数值就可以进行字符串内的多行匹配,设为
0(或未定义值) 相当于告诉 Perl
可以假定字符串都是单行的,从而能进行模式匹配的优化。当 $* 为 0
或未定义值时,对含有多个换行符的字符串进行模式匹配会产生很难
理解的结果。它默认为未定义值。(助记:* 匹配很多东西。)
该变量只影响对 "^" 和 "$" 的解释。即使在 "$* == 0"
时也可以搜索一个字面的换行符。
在现在的 Perl 里不应使用 $*,在模式匹配中可以用 "/s" 和 "/m"
修饰符取代 它的功能。
对 $* 赋非数值量会触发一个警告(并使 $* 表现为 "$* == 0"),对 $*
赋数值量则会隐含对其应用 "int"。
HANDLE->input_line_number(EXPR)
$INPUT_LINE_NUMBER
$NR
$. 为最后访问的文件句柄对应的当前行号。
Perl 中每个文件句柄都记录从其中读出的行数。(Perl
中行的概念也许和你不一 样,要看 $/ 的值是什么。)
当从某个文件句柄中读出一行(通过 readline() 或 "<>")或对其调用
tell() 或 seek() 时,$. 即成为那个句柄的行 计数器的别名。
你可以通过向 $. 赋值来调整计数器,但这并不会实际移动文件指针。
*局部化 $. 不会使对应文件句柄的行计数器局部化*,而只会局部化 $.
和文件句柄的别名关系。
关闭文件句柄时会复位 $.,但在没有 close()
就重新打开一个已打开的文件句柄 时不会这样。更多细节参见 "I/O
Operators" in perlop。"<>" 从不显式关闭文件,因此行号会在 ARGV
文件之间持续增长(不过请看看 "eof" in perlfunc 中的例子)。
你还可以用 "HANDLE->input_line_number(EXPR)"
访问一个给定文件句柄的
行计数器,这样就无需担心最后访问的是哪个句柄了。
(助记:很多程序用“.”表示当前行号。)
IO::Handle->input_record_separator(EXPR)
$INPUT_RECORD_SEPARATOR
$RS
$/ 为输入记录分隔符,默认为换行符。该变量会影响 Perl
对“行”这一概念 的理解。其功能类似于 awk 中的 RS
变量,在被设置为空字符串时同样
会将空白行作为终止标志。(空白行不能含有任何空格或制表符。)
你可以将其
设置为含有多个字符的字符串,以匹配多字符的终止标志;也可以设为
"undef" 以便一直读到文件结束。当文件含有连续的空白行时,把它设为
"\n\n" 和设为 "" 有少许不同:设为 ""
会把两个或更多连续的空白行视为单个 空白行;而设为 "\n\n"
则只是盲目地假定其后输入的字符属于下一段,即使
这些字符是换行符也一样。(助记:在引用诗句时会用 /
作为行间的分隔。)
local $/; # enable "slurp" mode
local $_ =; # whole file now here
s/\n[ \t]+/ /g;
切记:$/ 的内容是一个字符串,而不是正则表达式。awk
得在某些方面改进 一下了。:-)
将 $/
设为整数、存有整数的标量或可转换成整数的标量这些值的引用时,Perl
会尝试读入记录而不是行,最大记录长度就是引用的那个整数。因此这段
代码:
local $/ = \32768; # or \"32768", or \$var_containing_32768
open my $fh, $myfile or die $!;
local $_ = <$fh>;
会从 FILE 读取一条不长于 32768
字节的记录。如果你不是在读取一个面向记录 的文件(或者所用的 OS
没有面向记录的文件类型),那很可能每次读取都得到一
整块的数据。若某条记录比你所设置的记录长度还大,就会把该记录拆成
若干片 返回。
在 VMS 上,记录读取是用 "sysread"
的等价物完成的,因此最好不要在同一个
文件上混合使用记录和非记录读。(这不太可能成为问题,因为任何你想?
约锹寄J?读取的文件也许都不能在行模式下用。) 非 VMS 系统用普通
I/O 进行读取,因此 在一个文件中混合记录和非记录读是安全的。
参见 "Newlines" in perlport 以及 $.。
HANDLE->autoflush(EXPR)
$OUTPUT_AUTOFLUSH
$| 若将该变量设为非零值,就会立刻强制进行刷新,并且当前选中的输出通
道在每次 打印或写之后都会进行刷新。默认值为 0
(不管选中的通道实际上是否被系统所缓冲, $| 只是告诉你 Perl
是否在每次写完之后显式刷新)。典型情况下,若 STDOUT
的输出是终端则是行缓冲的,否则就是块缓冲。设置该变量在向管道或套
接字输出 时很有用,比如你正在 rsh 下运行一个 Perl
程序并且想在输出时马上就能看到
输出内容。该变量不影响输入缓冲。关于输入缓冲请参见 "getc" in
perlfunc。 (助记:when you want your pipes to be piping hot.)
IO::Handle->output_field_separator EXPR
$OUTPUT_FIELD_SEPARATOR
$OFS
$, 为 print 的输出域分隔符。通常 print
不经任何修饰就输出它的参数,要 得到更像 awk
的行为,可以将该变量设置成和 awk 的 OFS 变量一样
,以指定域之间打印什么。(助记:当 print
语句里有“,”时会打印的东西。)
IO::Handle->output_record_separator EXPR
$OUTPUT_RECORD_SEPARATOR
$ORS
$\ 为 print 的输出记录分隔符。通常 print
简单地原样输出它的参数,不增加
任何结尾的换行符或其他表征记录结束的字符串。要得到更像 awk
的行为, 可以将该变量设为同 awk 的 ORS 变量一样,以指定在 print
的结尾输出 什么。(助记:设置 $\ 而不是在 print
结尾加“\n”。另外,它长得和 $/ 很像,但却是你从 Perl
那里拿“回”的东西。) (译注:“回”原文为
单词“back”,还指代反斜杠“backslash”,起一语双关作用。)
$LIST_SEPARATOR
$" 该变量同 $,
类似,但应用于向双引号引起的字符串(或类似的内插字符串)
中内插数组和切片值的场合。默认为一个空格。(助记:我觉得显而易见?
?
$SUBSCRIPT_SEPARATOR
$SUBSEP
$; 为模拟多维数组时的下标分隔符。如果你这样引用一个散列元素
$foo{$a,$b,$c}
实际上意思就是
$foo{join($;, $a, $b, $c)}
但是别这么写
@foo{$a,$b,$c} # a slice--note the @
它的意思是
($foo{$a},$foo{$b},$foo{$c})
默认为“\034”,同 awk 的 SUBSEP
一样。如果你的散列键包含二进制数据, 可能 $;
就没法包含任何可靠的值了。
(助记:逗号(语法上的下标分隔符)是半个分号。是啊,我知道这完全没?
兴捣??,但 $, 已经被用做更重要的用途了。)
请考虑像 perllol 里说明的那样使用“真正的”多维数组。
$# 为打印数值时的输出格式。该变量是 awk 中 OFMT
变量一个粗糙的模仿尝试。 不过确实有段时间 awk 和 Perl
在什么可以看成数值的概念上有所分歧。它的 初始值是“%.*n*g”,*n*
是你所用系统上 float.h 中 DBL_DIG 宏的值。 这同 awk 的默认 OFMT
设置“%.6g”不一样,因此你需要显式设定 $# 以便 得到和 awk
一样的结果。(助记:# 是数值标志。)
不建议使用 $# 变量。
HANDLE->format_page_number(EXPR)
$FORMAT_PAGE_NUMBER
$% 为当前选中的输出通道的当前页码。同格式配合使用。 (助记:% 是
nroff 中的页码。)
HANDLE->format_lines_per_page(EXPR)
$FORMAT_LINES_PER_PAGE
$= 为当前选中的输出通道的当前页长度(可打印的行数)。默认为 60。
同格式配合使用。 (助记:符号 = 由两个水平行组成。)
HANDLE->format_lines_left(EXPR)
$FORMAT_LINES_LEFT
$- 为当前选中的输出通道的页面残留行数。同格式配合使用。
(助记:页面行数 - 已打印行数。)
@LAST_MATCH_START
@- $-[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])" 相同
HANDLE->format_name(EXPR)
$FORMAT_NAME
$~ 为当前被选中输出通道的当前报表格式名称。默认为文件句柄名。(助记?
?^ 的兄弟。)
HANDLE->format_top_name(EXPR)
$FORMAT_TOP_NAME
$^ 为当前被选中输出通道的当前页眉格式名称。默认为文件句柄名后加
_TOP。 (助记:指向页眉。)
IO::Handle->format_line_break_characters EXPR
$FORMAT_LINE_BREAK_CHARACTERS
$: 是一组字符,字符串可以在这些字符后断行以填充格式中的连续域(以 ^
开始)。 默认为 " \n-",使字符串能在空白或连字符处断开。
(助记:诗中的“冒号”是一行的一部分。)
IO::Handle->format_formfeed EXPR
$FORMAT_FORMFEED
$^L 退纸时格式应输出的内容。默认为 \f。
$ACCUMULATOR
$^A write() 对 format() 行的累加器的当前值。格式会调用 formline()
并将其结果放入 $^A。在调用对应的格式之后,write() 将 $^A
的内容打印出来并清空之。 因此你永远不可能看到 $^A
的内容,除非自己直接调用 formline() 并查看该变量 。参见 perlform
和 "formline()" in perlfunc。
$CHILD_ERROR
$? 由最近的管道关闭、反引号(``)命令、成功调用 wait() 和 waitpid()
或者 system() 操作符返回的状态信息。它就是由 wait()
系统调用返回的 16 位状态字
(或是由其他信息组合而成的类似值)。因此,子进程的退出值实际上是
("$? >> 8"),"$? & 127" 给出了导致进程结束的信号代码(如果存在),
而 "$? & 128" 会报告是否产生了内核转储。(助记:同 sh 和 ksh
类似。)
另外如果 C 中支持 "h_errno" 变量,在任意 "gethost*()"
函数失败时,该变量 的值将会通过 $? 返回。
如果已经为 "SIGCHLD" 安装了一个信号处理器,那么在处理器之外 $?
的值通常 是有问题的。
在 "END" 子程序里,$? 含有即将交给 "exit()" 的值。可以在 "END"
子程序 中修改 $? 以达到改变程序退出状态的效果。例如:
END {
$? = 1 if $? == 255; # die would make it 255
}
在 VMS 系统下,指示符 "use vmsish 'status'" 使得 $? 反映实际的
VMS 退出 状态,而不是默认的对 POSIX 状态的模拟;细节见 "$?" in
perlvms。
另见 错误指示器。
${^ENCODING}
为 Encode
对象的*对象引用*,用来将源代码转换成统一码。多亏有了该变量,
你的 Perl 脚本才不会被强制为 UTF-8 编码。默认为
*undef*。绝对不建议对 该变量进行直接操作。细节见 encoding。
$OS_ERROR
$ERRNO
$! 如果按数值使用该变量,就会得到 "errno"
变量的当前值;换句话说,如果
某个系统或者库函数调用失败了,就会设置该变量。这意味着 $!
的值仅当 *紧接*在一个失败之后时才有意义:
if (open(FH, $filename)) {
# Here $! is meaningless.
...
} else {
# ONLY here is $! meaningful.
...
# Already here $! might be meaningless.
}
# Since here we might have either success or failure,
# here $! is meaningless.
上述的*无意义*代表任何东西:零、非零、"undef"。成功的系统或库函?
?调用不会将该变量重置为零。
If used as a string, yields the corresponding system error
string. You can assign a number to $! to set *errno* if, for
instance, you want "$!" to return the string for error *n*, or
you want to set the exit value for the die() operator.
(Mnemonic: What just went bang?)
若作为字符串使用,则会产生对应的系统错误字符串。可以对 $!
赋一个数 来设置 *errno*,这样就能用 "$!" 得到错误 *n*
对应的字符串了,也可以 用来设置 die()
运算符所用的退出值。(助记:刚刚什么东西炸了?)
另见 错误指示器。
%! 当 $! 设置为某个值时 "%!" 的对应元素即为真值。例如,$!{ENOENT}
为真当且仅当 $! 的当前值为 "ENOENT";也就是说,若最后的错误是
"No such file or
directory"(或其他等价的东西:并不是所有操作系统都给出
完全一致的错误,当然也不可能都是同一种语言)。要检查某个特定的键?
谀愕南低?上是否有意义,可以用 "exists
$!{the_key}";要取得合法键的列表,可以用 "keys %!"。更多信息见
Errno,另外从前面的描述也可以得出 $! 的有效 范围。
$EXTENDED_OS_ERROR
$^E 同当前操作系统相关的错误信息。目前该变量仅在 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。(助记:额外的错误解释。)
(译注:英文中“额外”的单词为“Extra”。)
另见 错误指示器。