Perl中的特殊内置变量详细介绍

时间:2021-05-22

内置变量 $_:

先来看一个例子:
复制代码 代码如下:
#!/usr/bin/perl -w
@array = qw(a b c d);
foreach (@array) {
print $_," ";
}
例子的作用就是定义一个数组并把其中的元素打印出来,这里需要注意的是foreach循环部分,foreach循环的标准格式应该是:
复制代码 代码如下:foreach $element (@array){
......
}
其中数组@array将其中的元素依次赋值给$element,但是在上面那个程序中,我并没有这样做,在程序中,我就使用到了perl中内置的一个特殊变量 $_
在程序第五行中 foreach (@array) 实际上就是等于 foreach $_ (@array),在这里, $_是默认是输入/输出,因此,如果在程序中有类似的没有明确声明的变量位置的时候,就有可能能使用$_代替

内置变量 $$:

复制代码 代码如下:perl -e "sleep(5); print qq (The PID of process perl.exe is : $$)";
这是一句命令行上使用的perl程序,作用就是打印出一段话:print qq(The PID of process perl.exe is : $$) ,在这里,存在着特殊变量$$ ;
$$是当前perl解析器的进程ID(即,PID),大家可以将在段程序写在命令行上,该程序会在perl解析器运行5秒后打印出perl解析器的进程ID,大家可以在程序运行期间通过查看进程列表来确定打印结果是否正确。

内置变量 $!:


接下来是一个用来返回错误信息(或是错误号)的特殊变量。
为了省事,不写程序了,还是来个命令行的吧
复制代码 代码如下:perl -e "opendir FH,'c: one' or die qq (can't open:$!);";
这句话就是要打开C盘下的一个none目录(而实际上我的C盘中并没有此目录,之所以这样写的目的就是为了引起一个程序中的错误信息),如果没有打开的话,会执行后面的die qq(can't open:$!)
在这里,$!就指明了错误信息的内容,命令行会返回错误信息:
复制代码 代码如下:can't open:No such file or directory at -e line 1.
$!在open或是opendir中用的比较多(无论是打开文件还是管道或是其他)。

来个例子,说一个有意思的特殊内置变量
复制代码 代码如下:$text = "C:\test.txt";
{
open FH,$text or die "can't open:$!";
my $line = ;
close FH;
print $line;
}
print "#===========================# ";
{
undef $/;
open FH,$text or die "can't open:$!";
my $line = ;
close FH;
print $line;
}
=================================
C盘下的test.txt的内容是:
111111111111111111111111111
222222222222222222222222222
333333333333333333333333333
=================================
好,程序的运行结果是:
111111111111111111111111111
#===========================#
111111111111111111111111111
222222222222222222222222222
333333333333333333333333333

程序就不多废话了,作用就是读文件,关键部分在“$line = ”,尖括号操作符(即,<>)作用是读取一行文件内容(相信大多数教程或是书上都是这么写的),但是,这里所说的一行,实际上是有一个标准的,那就是当perl在遇到了换行符后,边认为是一行,而换行符默认情况下是由于$/这个特殊变量定义的,是缺省值。

也就是说,perl 在每次使用<>操作符读文件的时候,会先从$/中获得一个叫做“分隔符”的东西,并以该分隔符为标记来读取文件,如果按默认的$/来说,这个分割符就是一个换行符,所以,默认时,<>操作符才会每次读取一行文本。


在给出的例子中,有这样一句 :undef $/ ,也就是将$/设置为未定义的值,这样一来呢,$/就不再起作用了,因此,大家可以看到,第二次进行同样的操作的时候, <>操作符就不再是只读一行而是将文件内容全部读出来了。

接下来看一个会受到$/影响的内置变量,还是先说实例:
复制代码 代码如下:$text = "C:\test.txt";
open FH,$text or die "can't open:$!";
while () {
print "line $. is:$_";
}
close FH;
先来看循环中的:print "line $. is:$_"
程序的作用是读文件,并且,将文件逐行赋值给$_(因为只用了<>操作符而没有指定内赋值变量,因此,默认就是赋值给了$_);
但是这里除了$_,还有一个变量“$.”
我们来看一下结果:
复制代码 代码如下:line 1 is:111111111111111111111111111
line 2 is:222222222222222222222222222
line 3 is:333333333333333333333333333
可见,变量$.的作用是一个类似计数器的东西,但是,为什么刚开始我说$.会受到$/变量的影响呢 ?

将上面的例子稍做修改,再看一下:
复制代码 代码如下:$text = "C:\test.txt";
undef $/; # 注意,多加了这一行
open FH,$text or die "can't open:$!";
while () {
print "line $. is:$_";
}
close FH;

第二行多加了一句undef $/; ,上面已经说过它的作用了,来看一下这段程序运行的结果:
复制代码 代码如下:line 1 is:111111111111111111111111111
222222222222222222222222222
333333333333333333333333333
本来应该是三行的文本,不但被一次性打印出来,而且还指明了“line 1”(看来程序认为这个文本只有一行),为什么 ?

这是因为$.变量并不是一个单纯的行计数器,确切地说,可以说$.是一个对$/计数器,我们再来看一段程序大概就会明白了:

复制代码 代码如下:$text = "C:\a.txt";
$/ = ";"; # 注意这里,这里我并将$/设置为未定义,而是给其赋值为分号
open FH,$text or die "can't open:$!";
while () {
print "line $. is:$_ ";
}
close FH;

再看一下C盘下的a.txt的内容:
复制代码 代码如下:ddd;bbb;ccc;fff;eee;
就这么简单了。
看一下运行结果:
复制代码 代码如下:line 1 is:ddd;
line 2 is:bbb;
line 3 is:ccc;
line 4 is:fff;
line 5 is:eee;
看过这段程序应该就明白了吧。

好,$.已经讲得差不多了,接下来再说一个它的特性,仍然是看程序说话:
复制代码 代码如下:$text = "C:\test.txt";
open FH,$text or die "can't open:$!";
while () {
print "line $. is:$_ ";
}
print " ",$.;
close FH;
print " ",$.;
这个程序要注意的是最后三行中的两个print " ",$.;(一个是在关闭文件前,另外一个则是在关闭文件后)。
看一下执行结果:
复制代码 代码如下:line 1 is:111111111111111111111111111
line 2 is:222222222222222222222222222
line 3 is:333333333333333333333333333
3
0
结果的前三行刚才就已经知道了,这不是我们关心的,我们应该关心的是最后两行结果(即两个print " ",$.;的结果);
$.变量是具有记忆性的(从原理上来将,它是一个包变量),因此,在关闭文件前打印会发现,它的值是还没有变化的(这时的值和最后一次读完文件的值均为3);
而在关闭文件后,该变量又被重新初始化为0了。
这个特性大家注意一下就可以了,因为其中的原理涉及到了perl的作用域和包的一些知识,不是很容易说清楚,所以就不说了,如果对包和作用域有了解的读者对这部分即使我不讲他们也应该能理解的。

内置变量:$^O:

再说最后一个吧

说一个用来简单判断操作系统类型的,看个例子:
复制代码 代码如下:C:>perl -e "print $^O;";
MSWin32
注意,这里这个特殊变量$^O 最后一个字符是字母O,且大写。
如果是在linux下的话,结果就不是MSWin32了,而是Linux ;
这是一个判断环境的变量,简单实用。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章