天天看點

第6章 子過程:

第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 子過程屬性