像不少口语一样,Perl 提供了语言学捷径。上下文即是这样一个特性。阅读代码的无论是 编译器还是程序员,都可以通过现有信息了解到所期望结果的数量和操作符的类型,而不必 额外添加明确信息来消歧。Perl 中也存在其他类似的特性,包括本质上是代词的默认变量。
默认标量变量(也称为话题变量)$_
,是 Perl 中语言学捷径的最佳例证。它最显眼的地方 就是它的 “缺席”:当缺少一明确变量时,Perl 中许多内置操作是针对 $_
的内容进行的。 你仍可以将 $_
填入所缺变量的位置,但是这通常是多此一举。
举例来说,chomp
操作符移去任何尾随字符串的换行符序列:
在没有指明变量时,chomp
移去 $_
尾部的换行符,因此下列两行代码是等价的:
$_
在 Perl 中的功能等同于汉语中的代词“它”(英语中的代词 it)。第一行 读作 “chomp
它”,第二行则读作“chomp
”。当你不指明对什么做 chomp 操作时, Perl 理解你的意思,Perl 总是 chomp 它。
类似的,内置函数 say
和 print
在缺少参数时作用于 $_
之上:
Perl 的这套正则表达式装备 (regular_expressions) 同样可以在 $_
上进行匹配、 替换和转译操作:
Perl 中许多标量操作符(包括 chr
、ord
、lc
、length
、reverse
及 uc
) 在你不提供替代选项时,作用于默认标量变量上。
Perl 的循环指令 (looping_directives) 同样设置 $_
变量,比如用 for
遍历一个列表:
……或者是 while
:
……再或者是用 map
转换列表:
……又或者是用 grep
过滤列表:
如果你在用到 $_
的代码内调用函数,无论是隐式还是显式,可能导致 $_
的值被覆盖。 相似地,如果你编写了一个使用 $_
的函数,就有可能搅乱调用者对 $_
的利用。Perl 5.10 允许你用 my
将 $_
作为词法变量来声明,这样便可以避免上述行为。明智一点。
在本例子中,若 calculate_value()
或它偶然调用了其他函数导致 $_
的值改变,则在 整一次 while
循环中,此值将保持被改后的状态。用 my
来声明可以避免此类情况:
当然,使用带有具体名字的变量会比较清晰:
你可以在书面写作中用到“它”(英语:"it")的地方使用 $_
: 适度地、在小且精心圈定的范围内。
在 Perl 拥有一个隐式的标量变量的同时,它也有两个隐式数组变量。Perl 通过一个名为 @_
的数 组向函数传递参数。函数内部处理数组的操作符 (arrays) 默认影响这个数组。因此,以下二例代码 是等价的:
正如 $_
对应代词 它,@_
对应代词 它们。不同于 $_
,当你调用其他函数时, Perl 自动地为你局部化 @_
。数组操作符 shift
和 pop
在没有提供其他操作数时作用于 @_
。
在所有函数之外,默认数组变量 @ARGV
存有传递给程序的命令行参数。在函数 内 隐式用到 @_
的 同一批数组操作符,在函数外隐式地使用 @ARGV
。你不可以将 @_
用作 @ARGV
。
ARGV
有一个特殊的用法。如果你从空文件句柄 <>
读入,则 Perl 会将 @ARGV
中的每一个元素当作 文件的 名字 而打开。(如果 @ARGV
为空,Perl 会从标准输入读取。)这个隐含的 @ARGV
行为在编写 短小的程序(例如将输入逆序输出的命令行过滤器)时很有用:
如果你用一列文件作参数运行这个程序:
……结果应该会是一系列冗长的输出。不带参数运行时,你可以提供自己的标准输入:通过管道的方式接通其他程序, 或者直接从键盘打字。
Hey! The above document had some coding errors, which are explained below:
- Around line 5:
-
A non-empty Z<>
- Around line 13:
-
A non-empty Z<>