zhumao

新手上路

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

perl中的特殊内置变量(转)

学习perl中的基础。

先来一个例子吧
#!/usr/bin/perl
use warnings;
@array = qw(a b c d);
foreach (@array) {
print $_,"\n";
}
例子的作用就是定义一个数组并把其中的元素打印出来,这里需要注意的是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:\none' 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 "#===========================#\n";
{
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:$_\n";
}
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:$_\n";
}
print "\n",$.;
close FH;
print "\n",$.;
这个程序要注意的是最后三行中的两个print "\n",$.;(一个是在关闭文件前,另外一个则是在关闭文件后)。
看一下执行结果:
line 1 is:111111111111111111111111111
line 2 is:222222222222222222222222222
line 3 is:333333333333333333333333333
3
0
结果的前三行刚才就已经知道了,这不是我们关心的,我们应该关心的是最后两行结果(即两个print "\n",$.;的结果);
$.变量是具有记忆性的(从原理上来将,它是一个包变量),因此,在关闭文件前打印会发现,它的值是还没有变化的(这时的值和最后一次读完文件的值均为3);
而在关闭文件后,该变量又被重新初始化为0了。
这个特性大家注意一下就可以了,因为其中的原理涉及到了perl的作用域和包的一些知识,不是很容易说清楚,所以就不说了,如果对包和作用域有了解的读者对这部分即使我不讲他们也应该能理解的。

再说最后一个吧
说一个用来简单判断操作系统类型的,看个例子:
C:\>perl -e "print $^O;";
MSWin32
注意,这里这个特殊变量$^O 最后一个字符是字母O,且大写。
如果是在linux下的话,结果就不是MSWin32了,而是Linux ;
这是一个判断环境的变量,简单实用。
perl的内置特殊变量还有很多的,例如常用的还有@_、@ARGV、$ARGV、%INC、%ENV等等,有很多,不可能一一列举了,这里给出一个比较有总结性的列表,是chinaunix上perl社区的一个网友总结的,还算比较全:
$- 当前页可打印的行数,属于Perl格式系统的一部分
$! 根据上下文内容返回错误号或者错误串
$” 列表分隔符
$# 打印数字时默认的数字输出格式
$$ Perl解释器的进程ID
$% 当前输出通道的当前页号
$& 与上个格式匹配的字符串
$( 当前进程的组ID
$) 当前进程的有效组ID
$* 设置1表示处理多行格式.现在多以/s和/m修饰符取代之.
$, 当前输出字段分隔符
$. 上次阅读的文件的当前输入行号
$/ 当前输入记录分隔符,默认情况是新行
$: 字符设置,此后的字符串将被分开,以填充连续的字段.
$; 在仿真多维数组时使用的分隔符.
$? 返回上一个外部命令的状态
$@ Perl解释器从eval语句返回的错误消息
$[ 数组中第一个元素的索引号
$\ 当前输出记录的分隔符
$] Perl解释器的子版本号
$^ 当前通道最上面的页面输出格式名字
$^A 打印前用于保存格式化数据的变量
$^D 调试标志的值
$^E 在非UNIX环境中的操作系统扩展错误信息
$^F 最大的文件捆述符数值
$^H 由编译器激活的语法检查状态
$^I 内置控制编辑器的值
$^L 发送到输出通道的走纸换页符
$^M 备用内存池的大小
$^O 操作系统名
$^P 指定当前调试值的内部变量
$^R 正则表达式块的上次求值结果
$^S 当前解释器状态
$^T 从新世纪开始算起,脚步本以秒计算的开始运行的时间
$^W 警告开关的当前值
$^X Perl二进制可执行代码的名字
$_ 默认的输入/输出和格式匹配空间
$| 控制对当前选择的输出文件句柄的缓冲
$~ 当前报告格式的名字
$` 在上个格式匹配信息前的字符串
$’ 在上个格式匹配信息后的字符串
$+ 与上个正则表达式搜索格式匹配的最后一个括号
$< 当前执行解释器的用户的真实ID
$ 含有与上个匹配正则表达式对应括号结果
$= 当前页面可打印行的数目
$> 当前进程的有效用户ID
包含正在执行的脚本的文件名
$ARGV 从默认的文件句柄中读取时的当前文件名
%ENV 环境变量列表
%INC 通过do或require包含的文件列表
%SIG 信号列表及其处理方式
@_ 传给子程序的参数列表
@ARGV 传给脚本的命令行参数列表
@INC 在导入模块时需要搜索的目录列表
$-[0]和$+[0] 代表当前匹配的正则表达式在被匹配的字符串中的起始和终止的位置 。

posted on 2005-08-09 21:46  zhumao-2  阅读(444)  评论(0编辑  收藏  举报