1. 定义子程序
子程序由sub关键字定义花括号表示函数体范围。
子程序不需要事先声明。
如果定义了两个相同名字的子程序,后面的会覆盖前面的。
| sub marine { print "this is a test\n"; } &marine;
|
2. 子程序调用 &
用”&函数名(参数列表);“来调用子程序,如果不需要传入参数,就不加,”&函数名;“
&符号可以省略:
- 子程序在使用之前定义好了
- 调用子程序时,参数列表放在括号里。
&不可省略:子程序名字和perl默认函数名字相同时绝对不可以省略
3. 返回值
perl中所有的子程序都有返回值,所以perl默认以最后一次运算的结果作为返回值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| sub sum_of_fred_barney { print ("sum is ",($fred+$barney),"\n"); $fred+$barney; } $fred = 1; $barney = 1; print &sum_of_fred_barney,"\n"; 输出: sum is 2 2
sub sum_of_fred_barney { print ("sum is ",($fred+$barney),"\n"); } $fred = 1; $barney = 1; print &sum_of_fred_barney,"\n"; 输出: sum is 2 1
|
最后一次运算结果,而不是最后一行表达式,如下面这个例子
1 2 3 4 5 6 7 8 9 10 11 12
| $fred = 2; $barney = 1; sub sel { if ($fred > $barney) { $val = 1; } else { $val = 0; } } &sel; print '$val'," is $val\n";
|
return返回
如果子程序执行到一半需要返回,用return;
1 2 3 4 5 6 7 8
| sub find4{ foreach(@_) { if ($_ > 4) {return $_;} } -1; } @f4 = qw/1 3 2 1/; print &find4(@f4);
|
4. 参数
perl自动将参数化列表保存在数组**@_**中,在子程序定义的时候不需要写参数表。
1 2 3 4 5 6 7
| sub max { if($_[0] > $_[1]) { $_[0] ;} else { $_[1] ;} } $fred = 2; $barney = 1; print "the max of ",'$fred'," and ",'$barney'," is ",&max($fred,$barney),"\n";
|
子程序调用的时候有多余的参数,会被忽略,反正程序中也用不到。
也可以根据 标量上下文中的列表这个概念来判断传入的参数个数对不对,如果多了就输出一段警告。
1 2 3 4
| sub max { if(@_ != 2) print "WARNING!\n"; }
|
也可以传入任意长度的参数,只要是功能需要
1 2 3 4 5 6 7 8 9 10 11
| sub max{ $max_of_list = shift @_; foreach (@_) { if($max_of_list < $_) { $max_of_list = $_; } } $max_of_list; } @list = qw/1 2 3 4/; print "the max of ",'$fred'," and ",'$barney'," is ",&max(@list),"\n";
|
5. 子程序中的私有变量 my
用my操作符来定义子程序中的私有变量,作用域只是该子程序。
可以用来对子程序参数重命名,也就是将参数保存在这些私有变量里,因为默认的@_数组保存变量不好识别,变量多了不知道各个变量是什么意思。
1 2 3 4 5
| sub max { my($l,$r) = @_; if($l > $r) { $l; } else { $r; } }
|
my操作符不加()的时候只能声明单个变量。
6. 子程序持久性私有变量 state
用state声明,子程序在多次调用的时候保留该变量的值,类似于C++中的static变量。
7. 自定义 排序规则子程序(sort-definition subroutine)
通过自己定义规则子程序对元素进行排序。可以是正序、反序、或者按照键值对哈希排序等。
比如:
1 2 3 4
| sub sort_any { if($a>$b) {return -1;} else {return 1; } }
|
对于上面程序中的变量$a,$b是perl为我们定义好的,不需要自己定义,它们是来自排序列表中的两个元素。
子程序会返回一个数字,用来描述两个元素的比较结果。如果返回-1,表示$a应该在$b之前,返回1,$a应该在$b之后,返回0表示无所谓谁先谁后。上面程序中$a>$b时返回-1,表示将大的$a排在前面,也就是降序排列。
使用自定义排序规则
1 2 3 4 5 6 7 8
| sub sort_any { if($a>$b) {return -1;} else {return 1; } } @arr = qw/10 2 20 40/; @arr_sort = sort sort_any @arr; print "@arr_sort\n"; print "@arr\n";
|
另外,可以用飞船操作符<=>,无分号结尾
1 2
| sub sort_any { $a <=> $b } sub sort_any { $b <=> $a }
|
按照哈希值排序
其实是按照值对键进行排序,比如按照分数对人名进行排序。
1 2 3 4 5 6 7
| %h = ('dong',10,'wang',20,'liu',30); sub sort_hash { $h{$b}<=>$h{$a} } @l = sort sort_hash keys %h; foreach (@l) {print $_;print "\t";}
|