第6章 子過程:
像其他的語言一樣,Perl也支援自定義的子過程。(注:我們也把它們叫做函數,不過函數和子過程在perl裡一樣的東西。
有時候我們甚至叫它們方法,方法和函數或子過程是同樣的方式定義的,隻是調用方式不同)
1.0 文法:
聲明一個命名子過程,但不定義它,使用下面的形式:
sub NAME
sub NAME PROTO
sub NAME ATTRS
sub NAME PROTO ATTRS
聲明并且定義一個命名子過程,加上一個{};
對于沒有NAME的形式,你還必須提供調用子過程的方法,是以你必須儲存傳回值,因為這種形式的sub聲明方法不但在編譯的時候編譯,
同時也産生一個允許時的傳回值,是以我們就可以保證儲存它:
[root@master big]# cat a1.pl
use Data::Dumper;
$subref= sub { return aa};
my $xx= Dumper($subref);
print "111111111\n";
print $xx;
print "\n";
print "222222222222\n";
print $subref;
print "3333333333\n";
$yy=&$subref();
print $yy;
[root@master big]# perl a1.pl
111111111
$VAR1 = sub { "DUMMY" };
222222222222
CODE(0xcdf350)
3333333333
aa
use base qw(
Weixin::Message
Weixin::Client::Callback
Weixin::Client::Operate
Weixin::Client::Friend
Weixin::Client::Chatroom
Weixin::Client::Request
Weixin::Client::Cron
Weixin::Client::Plugin
Weixin::Client::Base
);
use MODULE qw(NAME1 NAME2 NAME2...)
直接調用子過程可以用下面的方法:
1.NAME(LIST) ##有圓括号時&是可選的
2.NAME LIST #如果預聲明/輸入了子過程,那麼圓括弧是選的
3. &$subref ##把目前的@_輸出到該子過程
2.0 語意:
在你記住所有文法前,你隻需要記住下邊這種定義子過程的普通方法:
[root@master big]# cat a2.pl
sub razzle{
print "Ok,you've been razzled.\n";
}
razzle();
[root@master big]# perl a2.pl
Ok,you've been razzled.
現在,如果你将設計一種可以支援不定數量的任意參數的語言,你最好讓你的語言在處理這些任意長的參數清單上容易些,
所有傳入Perl過程的參數都是以@_身份傳入的。 如果你調用一個有兩個參數的函數,它們在函數内部可以作為@_數組的前兩個成員通路:
$_[0] 和$_[1]
子過程(其他的程式塊也一樣)的傳回值是過程最後一個表達式的隻,或者你可以在子過程的任何一個地方明确使用一個return
語句來傳回值并且退出子過程
$subref= sub { return aa;print "bb\n"};
$yy=&$subref;
[root@master big]# cat a3.pl
sub test {
$a = shift;
$b = shift;
$c = shift;
return $a + $b + $c;
};
$xx=test(1,2,3);
print "$xx\n";
[root@master big]# perl a3.pl
6
2.2 錯誤提示
eval {return $a / $b} ;
if ($@){return aaaaaaaa}else{return bbbbbbbbbb};
$xx=test(9,3);
bbbbbbbbbb
$xx=test(9,0);
aaaaaaaa
3.0 傳入引用:
這裡有幾個簡單的例子,首先,讓我們定義一個函數,這個函數使用數組的引用作為參數,當這個數組非常大時,作為一個引用傳遞
要比傳入一長列值要快的多:
[root@master big]# cat a4.pl
sub sum {
my $aref = shift;
print "\@ref is @$aref\n";
foreach (@$aref) {$total += $_};
return $total;
my @a=(1, 4, 7);
$xx = sum(\@a);
print $xx;
print "\$total is $xx\n";
[root@master big]# perl a4.pl
@ref is 1 4 7
12
$total is 12
4.0 函數原型
Perl 可以讓你定義你自己的函數,這些函數可以像Perl的内建函數一樣調用,例如 push(@array,$item);
4.1 内聯常量函數:
帶有() 的函數原型表示這個函數沒有任何參數,就像内建函數time一樣
[root@master big]# cat a5.pl
sub PI () { 4 * atan2(1, 1) } ;
$xx=&PI();
print "\$xx is $xx\n";
[root@master big]# perl a5.pl
$xx is 3.14159265358979
[root@master big]#
5.0 子過程屬性