Perl学习笔记 Learning Perl Chapter IV
第四章 子程序,用户定义的函数,区别于内置函数
1.Defining a Subroutine 定义子程序
使用关键字sub:
sub routine { body }.
sub routine { body }.
2.Invoking a Subroutine 调用子程序
用 &subroutinename
3.Return Values 返回值
子程序中最后执行的语句的结果作为本子程序的返回值,如果子程序最后并不执行计算,不同的操作不同的上下文有不同返回值,如:
sub example{
$a+$b;
} #返回$a+$b的值
sub example{
print "what is this?\n";
} #返回1
sub example{
@a=qw/what the fuck/;
@b=sort @a;
} #返回3
sub example{
@a=qw/what the fuck/;
$b=sort @a; #返回undef
}
sub example{
@a=qw/again this array/;
@b=reverse @a; #返回3
}
sub example{
@a=qw/again this array/;
$b=reverse @a; #返回kcufehttahw
}
sub alternative{
if($a lt $b){
$b;}
else{
$a;}
} #返回较大值
4.Arguments 参数
可以给子程序传递参数,有意思的是,定义子程序时并不必使用形参,参数默认存在一个叫@_的数组中,@_是局部变量,在子程序内部可直接使用其中元素如$_[0]:
sub whichIsLarger{
if($_[0]>$_[1]){
$_[0];
}else{
$_[1];
}
}
$a=&whichIsLarger(10,12);
但是这种方式下,参数数目必须弄清楚,传递时,多余的参数值被忽略,缺省的参数值为undef
5.Private Variables in Subroutines 子程序中局部变量
理所应当的,子程序中可以定义自己的局部变量,使用关键字my:
sub example{
sub example{
my($a,$b)=@_;
……
}
6.Variable-Length Parameter Lists 变长参数列表
perl,可以给子程序传递任意长度的参数列表,如4中所述,也可以测试参数列表长度if(@_!= number)来处理特殊情况
一个小example做一个小总结:
#求数组中元素的最大值
@a=(1,4,2,8,5,7);
$maxone=&max(@a);
sub max{
my($res)=shift @_;
foreach (@_){
if($_>$res){
$res=$_;
}
}
$res;
}
但是,如果@a为空,返回值是什么? undef!
7.Notes on Lexical Variables 局部变量的一些说明
用my定义局部变量可以用在子程序以外的任何程序段中,器其作用域为包含它的最小程序模块
6中定义的局部变量实际上是在list上下文中,my同样可以用到scalar上下文中,如下例:
my($a) = @_; #list上下文:把@_中首元素的值赋给$a
my $a = @_; #scalar上下文:$a存储@_中元素的个数
可以看出,使用my,不加括号只是声明一个局部scalar变量,加括号声明局部数组,当然也可以这样声明数组:
my @arrayname;
8.The use strict Pragma use strict 预处理命令
perl太灵活,可能会带来一些编程上的麻烦,如:使用新变量不需先定义,这导致细微的拼写错误就相当于定义了个新变量,很难察觉
perl提供了use strict预处理命令,强制使用一系列更加严格的语法,比如新变量必须用my 定义,这样任何未定义的变量会使编译器报错。
推荐在程序中尽量使用use strict
9.The return Operator return 操作符
跟其他编程语言一样,用return可以让子程序立即返回一个值
10.Omitting the Ampersand 去掉&
在不引起歧义的前提下,调用子程序时不必要的&可以省略:
my $a = iAmSub(@iAmArgue);
注意:perl允许内置函数和自定义函数同名,此时,若想调用自定义函数,就必须使用&了
在已定义了子程序的情况下,参数列表的括号()也可以省略省略:
sub marine{
$_[0]+$_[1];
}
my $res = marine 123,124;
11.None-Scalar Return Values 非scalar类型的返回值
子程序的返回值可以是其他类型的值,比如一个数的序列,undef,空的list