Perl复习
第一章:Perl语言概述
特点
- 灵活性
- 不用编译器和链接器
- 提供了脚本语言所有功能,还有更多的功能
- 简单
- 良好的可移植性
- 可读性
### 缺点
- 语法冗余
第二章:简单变量
### 整型
- 整数存在浮点寄存器中,当作浮点数看待
- 8进制以0打头,16进制以0x打头
浮点数
- 浮点寄存器不能精确地存储浮点数
- 指数范围为 -30^9 到 +30^8
字符串
- 字符串地末尾并未含有隐含的NULL字符,NULL字符可以出现在串的任何未知
- 双引号内的字符串中支持简单变量替换
- 双引号内的字符串中支持转义字符
- 要在字符串中包含双引号或反斜线,则在其前加一个反斜线
- 反斜线可以取消变量替换
- 可以用 \nnn (八进制)或 \xnn (十六进制)来表示ASCII字符
- 单引号字符串
- 没有变量替换功能
- 反斜线不支持转义字符
- 可以跨多行
字符串和数值的互相转换
- 若字符串中含有非数字的字符,则从左起至第一个非数字的字符
变量初始值
- 所有的简单变量都有缺省初始值:“”,即空字符。
第三章:操作符
算术操作符
- 乘幂的基数不能为负
- 乘幂结果不能超过计算机表示的限制
- 取余的操作数如不是整数,四舍五入成整数后运算,运算符右侧不能为零
- 单目负可用于变量
整数比较操作符
- 操作符 <=> 结果为:
- 0 - 两个值相等
- 1 - 第一个值大
- -1 - 第二个值大
字符串比较操作符
- lt 小于
- gt 大于
- eq 等于
- le 小于等于
- ge 大于等于
- ne 不等于
- cmp 比较,返回1,0,或者-1
逻辑操作符
- 或:|| or
- 与:&& and
- 非:! not
- 异或:xor
位操作符
- 不能将&用于负整数,Perl会将它们转化为无符号数
赋值操作符
- ^= 位异或并赋值
- =可在一个赋值语句中出现多次
自增自减操作符
- 不要在一个变量两边同时使用这种符号
- 不要在变量自增/减后在同一表达式中再次使用
- 在Perl中++可用于字符串,但当结尾字符为 ‘z’,‘Z’, '9’时进位
- 不要使用 – ,perl将先将字符串转换为数字再进行自减
- 如果字符串中 含有非字母且非数字的字符,或数字位于字母中,则经过++运算前值转换为0,因此结果为1
字符串联接和重复操作符
- 联接:.
- 重复:x
- 联接且赋值:.=
逗号操作符
- 其前面的表达式先进行运算
- 使用此操作符的唯一理由是提高程序的可读性,将关系密切的两个表达式结合在一起
条件操作符
- 与C中类似,条件 ?值1:值2,当条件为真取值1,为假时取值2
- Perl5中,可以在赋值式左边使用条件操作符来选择被赋值的变量
第四章:列表和数组变量
### 列表
- 列表是包含在括号里的一序列的值,可以为任何数值,也可为空
- 空列表:()
- 只含有一个数值的列表与该数值本身不同,但可以相互转换或赋值
数组 – 列表的存贮
- 列表存贮于数组变量中,与简单变量不同,数组变量以字符 “@”打头
- 数组变量创建时初始值为空列表
- Perl用@和$来区分数组变量和简单变量,所以同一个名字可以同时用于数组变量和简单变量
- 数组的存取
- 对数组中的值通过下标存取,第一个元素下标为0,试图访问不存在的数组元素,则结果为NULL,但如果给超过数组大小的元素赋值,则数组自动增长,原来没有的元素值为NULL。
- 数组间拷贝
- 用数组给列表赋值
- 数组对简单变量的赋值
- 从标准输入(STDIN)给变量赋值
- 使用标准输入
<STDIN>
给数组赋值,使用Ctrl+Z+回车完成输入
- 字符串中的方括号和变量替换
"$var[0]"
为数组@var的第一个元素。"$var\[0]"
将字符"["转义,等价于"$var"."[0]"
, $var 被变量替换,[0]保持不变。"${var}[0]"
亦等价于"$var"."[0]"
。"$\{var}"
则取消了大括号的变量替换功能,包含文字:${var}.
- 列表范围
- 用于实数
- 用于字符串
- 可包含变量或表达式
- 数组的输出
- 括号+数组
- 引号+数组
- 列表/数组的长度
- 当数组变量出现在预期简单变量出现的地方,Perl解释器取其长度
- 子数组
- 可以用子数组形式来交换元素
- 有关数组的库函数
- sort – 按字符顺序排序
- reverse – 反转数组
- chop – 数组去尾
- chop的意义是去掉STDIN(键盘)输入字符串时最后一个字符--换行符。
- 如果作用到数组上,则将数组中每一个元素都做如此处理
- join/split --连接/拆分
- join的第一个参数是连接所用的中间字符,其余则为待连接的字符数组
第五章:文件读写
打开、关闭文件
- 语法为open(filevar, filename),其中filevar为文件句柄,或者说是程序中用来达标某文件的代号,filename为文件名,其路径可为相对路径,亦可为绝对路径
- 打开文件时必须决定访问模式,在Perl中有三种访问模式:读、写和添加。后两种模式的区别在于写模式将原文件覆盖,原有内容丢失,形式为:
open(outfile,">outfile")
- 添加模式则在源文件的末尾处继续添加内容,形式为:
open(appendfile,">>appendfile")
- 不能对文件同时进行读和写/添加操作
- open的返回值用来确定打开文件的操作是否成功,当其成功时返回非零值,失败时返回零
- 当文件操作完毕后,用
close(myfile);
关闭文件。
读文件
- 语句
$line=<MYFILE>
从文件中读取一行数据存储到简单变量$line中并把文件指针向后移动一行。 <STDIN>
为标准输入文件,通常为键盘输入,不需要打开。- 语句
@array=<MYFILE>
把文件的全部内容读入数组@array,文件的每一行(含回车符)为@array的一个元素。
写文件
open(outfile, ">outfile") #打开对应的文件
print outfile ("具体内容!")
- STDOUT,STDERR为标准输出和标准错误文件,通常为屏幕,且不需要打开。
判断文件状态
- 文件测试操作符:
-op expr
命令行参数
- 像C一样,Perl有存储命令行参数的数组
@ARGV
,可以用来分别处理各个命令行参数 $ARGV[0]
是第一个参数
# An example
$count = @ARGV;
print "The length of the command arguments is: $count.\n";
print "The arguments are: \n";
for($i=0;$i<$count;$i++){
print @ARGV[$i]." ";
}
print "\n";
- Perl中,
<>
操作符实际上是对数组@ARGV
的隐含的引用,其工作原理为:- 当Perl解释器第一次看到
<>
时,打开以$ARGV[0]
为文件名的文件 - 执行动作
shift(@ARGV);
即把数组@ARGV
的元素向前移动一个,其元素数量即减少了一个 <>
操作符读取在第一步打开的文件中的所有行- 读完后,解释器回到第一步重复
- 当Perl解释器第一次看到
打开管道
- 用程序的形式也可以像命令行一样打开和使用管道
第六章:模式匹配
简介
- 模式指在字符串中寻找的特定序列的字符,由反斜线包含:
/def/
即模式def
。 - 其用法如结合函数
split
将字符串用某种模式分成多个单词:@array=split(//,$line);
操作匹配符
=~
检验匹配是否成功:$result=$var=~/abc/;
若在该字符串找到了该模式,则返回非零值,即true
,不匹配则返回0,即false
。!=~
则相反。
模式中的特殊字符
-
字符
+
-
+
意味着一个或多个相同的字符。 -
它尽量匹配尽可能多的相同字符。
-
当一行中各单词间的空格多于一个时,可以如下分割:
@array=split(/+/,$line);
split
函数每次遇到分割模式,总是开始一个新单词,因此若$line
以空格打头,则@array
的第一个元素即为空元素。但其可以区分是否真有单词,如若
$line
中只有空格,则@array
则为空数组。且上例中
TAB
字符被当作一个单词。
-
-
字符
[]
和[^]
[]
意味着匹配一组字符中的一个^
表示除其之外的所有字符。
-
字符
*
和?
- 它们与
+
类似,区别在于*
匹配0个,1个或多个相同字符,?
匹配0个或1个该字符。
- 它们与
转义字符
- 如果想在模式中包含通常被看作特殊意义的字符,须在其前加斜线
\
。 - 斜线的表示为
/\\/
匹配任意字母或数字
/[0-9]/ # 任意数字
/[a-z]/ # 任意小写字母
/[A-Z]/ # 任意大写字母
/[0-9a-zA-Z] # 任意数字,大小写字母
锚模式
锚 | 描述 |
---|---|
^ 或者\A | 仅匹配串首 |
$ 或者\Z | 仅匹配串尾 |
\b | 匹配单词边界 |
\B | 单词内部匹配 |
模式中的变量替换
- 将模式用字符串变量替换
- 使用变量替换时,需对字符串变量中的特殊字符进行转义(如
\
)
字符范围转义
匹配任意字符
- 字符
.
匹配除换行符外的所有字符,通常与*
合用
匹配指定数目的字符
- 字符对
{}
指定所匹配字符的 出现次数
指定选项
- 字符
|
指定两个或多个选择来匹配模式
模式的部分重用
- 当模式中匹配相同的部分出现多次时,可用括号括起来,用
\n
来多次引用。
转义和特定字符的执行次序
特殊符号 | 描述 |
---|---|
( ) | 模式内存 |
+*?{} | 出现次数 |
^$\b\B | 锚 |
` | ` |
指定模式定界符
- 缺省的,模式定界符为反斜线
/
,但其可用字母m
自行指定
# An example
m!/u/abc/def/fff! # 等价于
/\/u\/abc\/def\/fff/
- 当用字母
'
作为定界符时,不做变量替换 - 当用特殊字符作为定界符时,其转义功能或特殊功能即不能使用
模式次序变量
- 在模式匹配后调用重用部分的结果可用变量
$n
,全部的结果用变量$&
。
模式匹配选项
选项 | 描述 |
---|---|
g | 匹配所有可能的模式 |
l | 忽略大小写 |
m | 将串视为多行 |
o | 只赋值一次 |
s | 将串视为单行 |
x | 模式中的空白 |
-
选项
m
- 在此情况下,
^
符号匹配字符串的起始或新的一行的起始,$
符号匹配任意行的末尾
- 在此情况下,
-
选项
o
$var = 1; $line = <STDIN>; while ($var < 10) { $result = $line =~ /$var/o; $line = <STDIN>; $var++; } # 每次均匹配/1/ 。
-
选项
s
/a.*bc/s
匹配字符串axxxxx \nxxxxbc
,但/a.*bc/
则不匹配该字符串。
替换操作符
-
语法为:
s/pattern/replacement/
,其效果为将字符串中与pattern
相匹配的部分换成replacement
。 -
在替换部分可使用模式次序变量
$n
,如s/(\d+)/[$1]/
,但在替换部分不支持模式的特殊字符,如{},*,+
等 -
替换操作符的选项
选项 描述 g
匹配所有可能的模式 l
忽略大小写 m
将串视为多行 o
只赋值一次 s
将串视为单行 x
模式中的空白 e
替换字符串作为表达式 # e 选项把替换部分的字符串看作表达式,在替换之前先计算其值,即将字符串重复相应的次数。 $string = "1abc1"; $string =~ s/\d+/$& x 2/e; # $string = 11abc1
翻译操作符
-
这是另一种替换方式,语法如:
tr/string1/string2/
。同样,string2
作为替换部分,但其效果是把string1
中的第一个字符换为string2
中的第一个字符,把string1
中的第二个字符替换为string2
中的第二个字符,依此类推。$string = "abcdefghicba"; $string =~ tr/abc/def/; # now string = "defdefghifed"
-
当
string1
比string2
长时, 其多余字符替换为string2
的最后一个字符 -
当
string1
中同一个字符出现多次时, 将使用第一个替换字符 -
翻译操作符的选项
选项 描述 c
翻译所有未指定字符 d
删除所有指定字符 s
把多个相同的输出字符缩成一个
扩展模式匹配
-
PERL 支持PERL4 和标准UNIX 模式匹配操作所没有的一些模式匹配能力。其语法为:
(?<c>pattern)
,其中c
是一个字符,pattern
是起作用的模式或子模式。-
不存贮括号内的匹配内容在 PERL 的模式中,括号内的子模式将存贮在内存中,此功能即取消存贮该括号内的匹配内容, 如
/(?:a|b|c)(d|e)f\1/
中的\1
表示已匹配的d
或e
,而不是a
或b
或c
。 -
内嵌模式的选择
通常模式选项置于其后 , 有四个选项:
i 、m、s 、x
可以内嵌使用,语法为:/(?option)pattern/
, 等价于/pattern/option
。 -
肯定的和否定的预见匹配
肯定的预见匹配语法为
/pattern(?=string)/
,其意义为匹配后面为string
的模式, 相反的,(?!string)
意义为匹配后面非string
的模式$string = "25abc8"; $string =~/abc(?=[0-9])/; $matched = $&; print "$matched\n"; # $&为已匹配的模式 此处为abc 而不是abc8 $string = "25abcbd33abc23"; @word = $string =~/abc(?![a-zA-Z])/g; $count=@word; print $count."\n"; print "@word\n"; # @word 长度为1,内容为abc
-
模式注释
Perl5中可以在模式中使用
?#
来加注释,如if($string=~/(?i)[a-z]{2,3}(?# match two or three alphabetic characters))/
-
第七章:控制结构
条件判断
if ( <expression> ) {
<statement_block_1>
}
elsif ( <expression> ) {
<statement_block_2>
}
...
else {
<statement_block_3>
}
循环判断
# 1 、while 循环
while ( <expression> ) {
<statement_block>
}
# 2 、until 循环
until ( <expression> ) {
<statement_block>
}
类C的for循环
for ($count=1; $count <= 5; $count++) {
# statements inside the loop go here
}
# 下面是在for 循环中使用逗号操作符的例子:
for($line = <STDIN>, $count = 1; $count <= 3; $line =<STDIN>,$count++)
{
print ($line) ;
}
# 它等价于下列语句:
$line = <STDIN>;
$count = 1;
while ($count <= 3) {
print ($line);
$line = <STDIN>;
$count++;
}
针对列表(数组)每个元素的循环:foreach
foreach localvar ( list expr ) {
statement_block;
}
# 例:
@words =("the","Xian","Bei","San");
foreach $word (@words) {
if ( $word eq "the" ) {
print ( "found the word 'the'\n" ) ;
}
}
- 此处的循环变量
localvar
是个局部变量,如果在此之前它已有值, 则循环后仍恢复该值。 - 在循环中改变局部变量, 相应的数组变量也会改变
do
循环
do {
statement_block
} while_or_until (condexpr);
# do 循环至少执行一次循环。
循环控制
- 退出循环为
last
,与C中的break
作用相同 - 执行下一个循环为
next
,与C中的continue
作用相同 - Perl特有的一个命令是
redo
,其含义是重复此次循环,即循环变量不变,回到循环起始点,但redo
命令在do
循环中不起作用
传统的goto label;
语句
单行条件
-
语法为
statement keyword condexpr
。其中keyword
可为if、unless、while 或until
$var= 2; print ("Not zero yet $var.\n") while ($var-- > 1); print ("This is zero $var. \n " ) if ($var == 0); print ("This is zero $var.\n") unless ($var != 0); print ("Not zero yet $var. \n") until ($var-- == -2); print "the final value is $var\n";
-
虽然条件判断写在后面, 但却是先执行的
第八章:子程序
定义
-
子程序即执行一个特殊任务的一段分离的代码,它可以减少重复代码且使程序易读。
-
Perl中,子程序可以出现在程序的任何地方。
-
定义方法为:
sub subroutime{ state ments; }
调用
-
用
&
调用&subname; . . . sub subname{ . . . }
-
先定义后调用,可以省略
&
符号(类似C中调用在定义前)sub subname{ . . . } . . . subname;
-
前向引用,先定义子程序名,后再定义子程序体(类似C中先声明,后定义)
sub subname; . . . subname; . . . sub subname{ . . . }
返回值
- 缺省的,子程序中最后一个语句的值将用作返回值
- 语句
return(retval)
,retval
可以为列表
局部变量
- 子程序中局部变量的定义有两种方法:
my
和local
- 区别:
my
定义的变量只在该子程序中存在local
定义的变量不存在于主程序中,但存在于该子程序和该子程序调用的子程序中
子程序参数传递
-
形式:
&sub1($number1, $number2, $nubmer3 ); . . . sub sub1{ my($number1, $number2, $number3) = @_; . . . }
-
传递数组
&addlist (@mylist) ; &addlist ("14", "6", "11"); &addlist ($value1, @sublist, $value2); ... sub addlist { my (@list) = @_; ... }
-
参数为数组时,子程序只将它赋给一个数组变量。但简单变量和数组变量可以同时传递
sub twolists { my (@list1, @list2) = @_; } # @list2 必然为空。 &twoargs(47, @mylist); #47 赋给$scalar, @mylist 赋给@list &twoargs(@mylist) ; # @mylist 的第一个元素赋给$scalar,其余的元素赋给@list . . . sub twoargs { my ($scalar, @list) = @_; . . . }
递归子程序
- Perl中,子程序可以互相调用,其调用方法与上述相同,当调用该子程序本身时,即成了递归子程序。
- 递归子程序的两个条件:
- 除了不被子程序改变的变量外,所有的变量必须是局部的
- 该子程序要含有停止调用本身的代码
用别名传递数组参数
-
用
&my_sub(@array)
将把数组@array
的数据拷贝到子程序的变量@_
中,当数组很大时,开销较大,可以使用别名传参,对该数组直接操作(类似C中的传递指针)。形式如下:@myarray = ( 1 , 2 , 3 , 4 , 5 ) ; &my_sub(*myarray); . . . sub my_sub { local (*subarray) = @_; print "@subarray\n"; . . . }
-
此方法类似于C 语言中的传递数组的起始地址指针, 但并不一样,在定义数组的别名之后,如果有同名的简单变量,则对该变量也是起作用的。
$foo = 26; @foo = ("here's" , "a" , " list" ) ; &testsub (*foo); sub testsub { local (*printarray) = @_; @foo[3] = "of yeshou\n"; $printarray = 61; } print $foo."\n"; # 61 print "@foo\n"; # here's a list of yeshou
-
用别名可以传递多个数组
@array1 = (1, 2, 3); @array2 = (4, 5, 6); &two_array_sub (*array1, *array2); sub two_array_sub { local(*subarray1, *subarray2) = @_; print "sub1:@subarray1\tsub2:@subarray2"; # sub1:1 2 3 sub2:4 5 6 @subarray1[3]=114; @subarray2[3]=514; } print "array1:@array1\tarray2:@array2"; # array1:1 2 3 114 array2:4 5 6 514
预定义的子程序
-
PERL5 预定义了三个子程序,分别在特定的时间执行,它们是:
-
BEGIN 子程序在程序启动时被调用;
-
END 子程序在程序结束时被调用;
-
AUTOLOAD 子程序在找不到某个子程序时被调用。你可以自己定义它们, 以在特定时间执行所需要的动作。
BEGIN { print("Hi! Welcome to Xianbei! \n" ) ; } AUTOLOAD{ print("subroutine $AUTOLOAD not found\n"); # 变量$AUTOLOAD 即未找到的子程序名 print("arguments passed: @_\n"); } END { print "114 514 1414914\n"; } &test; # output: # Hi! Welcome to Xianbei! # subroutine main::test not found # arguments passed: # 114 514 1414914
-
第九章:关联数组/哈希表
数组变量的限制
-
很难记住哪个元素存贮的什么内容
# an example: find the capitalized words and count. while($inputline=<STDIN>){ while($inputline=~/\b[A-Z]\S+/g){ $word = $&; $word=~s/[;.,:-]$//; for($count=1;$count<=@wordlist;$count++){ $found=0; if($wordlist[$count-1] eq $word){ $found=1; $wordcount[$count-1]+=1; last; } } if($found==0){ $oldlength=@wordlist; @wordlist[$oldlength]=$word; @wordcount[$oldlength]=1; } } } print ("Capitalized words and number of occurrence:\n"); for($count=1;$count<=@wordlist;$count++){ print ("@wordlist[$count-1]:@wordcount[$count-1]\n"); } print "\n@wordlist \n@wordcount\n"; # Input: # Here is a line of Input. # There Input contains some Capitalized words. # ^Z # Output: # Capitalized words and number of occurrence: # Here:1 # Input:2 # There:1 # Capitalized:1 # Here Input There Capitalized # 1 2 1 1
定义
- Perl 定义了另一种数组,可以用任意简单变量值来访问其元素, 这种数组叫做关联数组, 也叫哈希表。
- 为了区分关联数组变量与普通的数组变量,Perl 使用%作为其首字符, 而数组变量以@打头。
- 与其它变量名一样, %后的第一个字符必须为字母, 后续字符可以为字母、数字或下划线。
访问关联数组的元素
- 关联数组的下标可以为任何简单/标量值,访问单个元素时以
$
符号打头,下标用大括号围起来。 - 简单变量也可以作为下标
增加元素
-
创建一个关联数组元素最简单的方法是赋值
-
如语句
$fruit{"bananas"} = 1;
把1 赋给关联数组%fruit
下标为bananas
的元素, 如果该元素不存在, 则被创建, 如果数组%fruit 从未使用过, 也被创建。# another example while($inputline=<STDIN>){ while($inputline=~/\b[A-Z]\S+/g){ $word=$&; $word=~s/[;.,:-]$//; $wordlist{$word}+=1; } } print("Capitalized words and number of occurrences:\n"); foreach $capword (keys(%wordlist)){ #内嵌函数keys()返回关联数组的下标列表 print ("$capword: $wordlist{$capword}\n"); } # Input: # Here is a line of Input. # This Input contains some Capitalized words. # ^Z # Output: # Capitalized words and number of occurrences: # Input: 2 # Here: 1 # This: 1 # Capitalized: 1
-
关联数组总是随机存贮的,因此当你用
keys()
访问其所有元素时,不保证元素以任何顺序出现,特别值得一提的是,它们不会以被创建的顺序出现。 -
要想控制关联数组元素出现的次序,可以用
sort( )
函数对keys()
返回值进行排列,如:foreach $capword (sort keys(%wordlist))
创建关联数组
-
可以用单个赋值语句创建关联数组, 如:
%fruit = ("apples",17,"bananas",9,"oranges","none");
此语句创建的关联数组含有下面三个元素:
-
下标为apples 的元素, 值为17
-
下标为bananas 的元素, 值为9
-
下标为oranges 的元素, 值为none
用列表给关联数组赋值时,Perl5 允许使用"=>“或” , “来分隔下标与值, 用”=>"可读性更好些, 上面语句等效于:
%fruit = ("apples"=>17,"bananas"=>9,"oranges"=>"none");
-
从数组变量复制到关联数组
-
与列表一样, 也可以通过数组变量创建关联数组, 当然, 其元素数目应该为偶数
@fruit = ("apples",17,"bananas",9,"oranges","none"); %fruit = @fruit;
-
可以把关联数组赋给数组变量
%fruit = ("grapes",11,"lemons",27); @fruit = %fruit; # 注意,此语句中元素次序未定义,那么数组变量@fruit 可能为("grapes",11,"lemons",27)或("lemons",27,"grapes",11)。
-
关联数组变量之间可以直接赋值, 如:
%fruit2 = %fruit1
-
可以把数组变量同时赋给一些简单变量和一个关联数组变量
-
关联数组可以通过返回值为列表的内嵌函数或用户定义的子程序来创建
元素的删除
- 删除元素的方法是用内嵌函数
delete
,如:delete($fruit{"lime"});
- 一定要使用
delete
函数来删除关联数组的元素, 这是唯一的方法。 - 一定不要对关联数组使用内嵌函数
push、pop、shift
及splice
,因为其元素位置是随机的。
列出数组的索引和值
keys()
函数返回关联数组下标的列表- 内嵌函数
values()
返回关联数组值的列表
用关联数组循环
- 利用
keys()
函数的foreach
循环语句, 这种循环效率比较低, 因为每返回一个下标, 还得再去寻找其值 - 使用内嵌函数
each()
,each()
函数每次返回一个双元素的列表, 其第一个元素为下标,第二个元素为相应的值, 最后返回一个空列表。 - 千万不要在
each()
循环中添加或删除元素,否则会产生不可预料的后果。
第十章:文件系统
文件输入/输出函数
- 基本I/O函数
open
: 允许程序访问文件close
: 终止文件访问print
: 文件写入字符串write
: 向文件写入格式化信息printf
: 格式化字符串并输出到文件
指定读写权限
- 打开一个既可读又可写的文件方法是在文件名前加上
+>
,如:open(READWRITE, "+>file1");
- 也可用前缀
+<
指定可读写权限。
print
,printf
和write
函数
print
是这三个函数中最简单的, 它向指定的文件输出, 如果未指定, 则输出到当前缺省文件中,若未调用select
, 则为STDOUT
printf
函数先格式化字符串再输出到指定文件或当前缺省文件中
select
函数
select
函数将通过参数传递的文件变量指定为新的当前缺省文件, 如:select(MYFILE);
eof
函数
eof
函数查看最后一次读文件操作是否为文件最后一个记录,如果是, 则返回非零值, 如果文件还有内容, 返回零。- 一般情况下,对
eof
的调用不加括号,因为eof
和eof()
是等效的,但与<>
操作符一起使用时,eof
和eof()
就不同了。- 命令行传入多个文件时,只有所有文件都读过了,
eof()
才返回真,如果只是多个文件中前几个的末尾,返回值为假,因为还有要读取的输入。而eof
每读取完一个文件返回值就为真。
- 命令行传入多个文件时,只有所有文件都读过了,
间接文件变量
- 对于上述各函数
open
,close
,print
,printf
,write
,select
和eof
,都可以用简单变量来代替文件变量,这时,简单变量中所存贮的字符串就被看作文件变量名 - 函数
open
,close
,write
,select
和eof
还允许用表达式来替代文件变量,表达式的值必须是字符串, 被用作文件变量名。
第十一章:包和模块
定义
- Perl 中每个包有一个单独的符号表,定义语法为:
package mypack;
- 此语句定义一个名为 mypack 的包,在此后定义的所有变量和子程序的名字都存贮在该包关联的符号表中,直到遇到另一个 package 语句为止。
- 每个符号表有其自己的一组变量、子程序名,各组名字是不相关的,因此可以在不同的包中使用相同的变量名,而代表的是不同的变量。
- 从一个包中访问另外一个包的变量,可通过"
包名 + 双冒号(::) + 变量名
" 的方式指定。 - 存贮变量和子程序的名字的默认符号表是与名为 main的包相关联的。
- 如果在程序里定义了其它的包,当你想切换回去使用默认的符号表,可以重新指定main包:
package main;
- 特殊变量 _PACKAGE_ 用于输出包名:
BEGIN 和 END 模块
-
Perl语言提供了两个关键字:
BEGIN,END
。它们可以分别包含一组脚本,用于程序体运行前或者运行后的执行。 -
语法格式如下:
BEGIN{...} END{...}
-
每个 BEGIN 模块在 Perl 脚本载入和编译后但在其他语句执行前执行。
-
•每个 END 语句块在解释器退出前执行。
Perl 模块
-
Perl5 中用Perl包来创建模块。
-
Perl 模块是一个可重复使用的包,模块的名字与包名相同,定义的文件后缀为 .pm。
# 定义了一个模块 Foo.pm,代码如下所示: #!/usr/bin/perl package Foo; sub bar { print "Hello $_[0]\n" } sub blat { print "World $_[0]\n" } 1;
- 函数 require 和 use 将载入一个模块。
- @INC 是 Perl 内置的一个特殊数组,它包含指向库例程所在位置的目录路径。
- require 和 use 函数调用 eval 函数来执行代码。
- 末尾 1; 执行返回 TRUE,这是必须的,否则返回错误。
-
Require 和 Use 函数
# use require function #!/usr/bin/perl require Foo; Foo::bar("a"); Foo::blat("b"); # use user function #!/usr/bin/perl use Foo; bar("a"); blat("b");
require
引用需要使用包名指定函数,而use
不需要require
用于载入module或perl程序(.pm后缀可以省略,但.pl必须有)- Perl
use
语句是编译时引入的,require
是运行时引入的 - Perl
use
引入模块的同时,也引入了模块的子模块。而require
则不能引入,要在重新声明 use
是在当前默认的@INC里面去寻找,一旦模块不在@INC
中的话,用use
是不可以引入的,但是require
可以指定路径use
引用模块时,如果模块名称中包含::
双冒号,该双冒号将作为路径分隔符,相当于Unix下的/或者Windows下的\。
Perl面向对象
-
实现方法:
- 基于匿名哈希表的方式,每个对象实例的实质就是一个指向匿名哈希表的引用。在这个匿名哈希表中,存储了所有的实例属性。
- 基于数组的方式,在定义一个类的时候,我们将为每一个实例属性创建一个数组,而每一个对象实例的实质就是一个指向这些数组中某一行索引的引用。在这些数组中,存储着所有的实例属性。
-
Perl 提供了
bless()
函数,bless
是用来构造对象的, 通过bless
把一个引用和这个类名相关联,返回这个引用就构造出一个对象。 -
创建和使用对象
- 创建一个类的实例 (对象) 我们需要定义一个构造函数,大多数程序使用类名作为构造函数,Perl 中可以使用任何名字。
- 你可以使用多种 Perl 的变量作为 Perl 的对象。大多数情况下我们会使用引用数组或哈希。
-
定义方法
- Perl面向对象中Perl的方法定义不提供任何特别语法,但规定方法的第一个参数为对象或其被引用的包。
Use** 函数
# use require function #!/usr/bin/perl require Foo; Foo::bar("a"); Foo::blat("b"); # use user function #!/usr/bin/perl use Foo; bar("a"); blat("b");
require
引用需要使用包名指定函数,而use
不需要require
用于载入module或perl程序(.pm后缀可以省略,但.pl必须有)- Perl
use
语句是编译时引入的,require
是运行时引入的 - Perl
use
引入模块的同时,也引入了模块的子模块。而require
则不能引入,要在重新声明 use
是在当前默认的@INC里面去寻找,一旦模块不在@INC
中的话,用use
是不可以引入的,但是require
可以指定路径use
引用模块时,如果模块名称中包含::
双冒号,该双冒号将作为路径分隔符,相当于Unix下的/或者Windows下的\。
- Perl面向对象中Perl的方法定义不提供任何特别语法,但规定方法的第一个参数为对象或其被引用的包。
Perl面向对象
-
实现方法:
- 基于匿名哈希表的方式,每个对象实例的实质就是一个指向匿名哈希表的引用。在这个匿名哈希表中,存储了所有的实例属性。
- 基于数组的方式,在定义一个类的时候,我们将为每一个实例属性创建一个数组,而每一个对象实例的实质就是一个指向这些数组中某一行索引的引用。在这些数组中,存储着所有的实例属性。
-
Perl 提供了
bless()
函数,bless
是用来构造对象的, 通过bless
把一个引用和这个类名相关联,返回这个引用就构造出一个对象。 -
创建和使用对象
- 创建一个类的实例 (对象) 我们需要定义一个构造函数,大多数程序使用类名作为构造函数,Perl 中可以使用任何名字。
- 你可以使用多种 Perl 的变量作为 Perl 的对象。大多数情况下我们会使用引用数组或哈希。
-
定义方法
- Perl面向对象中Perl的方法定义不提供任何特别语法,但规定方法的第一个参数为对象或其被引用的包。