?
一、require函數(shù)
? 1、require函數(shù)和子程序庫
? 2、用require指定Perl版本 二、包
? 1、包的定義
? 2、在包間切換
? 3、main包
? 4、包的引用
? 5、指定無當(dāng)前包
? 6、包和子程序
? 7、用包定義私有數(shù)據(jù)
? 8、包和系統(tǒng)變量
? 9、訪問符號(hào)表 三、模塊
? 1、創(chuàng)建模塊
? 2、導(dǎo)入模塊
? 3、預(yù)定義模塊
一、require函數(shù) ????用require函數(shù)可以把程序分割成多個(gè)文件并創(chuàng)建函數(shù)庫。例如,在myfile.pl中有定義好的Perl函數(shù),可用語句require
("myfile.pl");
在程序中包含進(jìn)來。當(dāng)Perl解釋器看到這一語句,就在內(nèi)置數(shù)組變量@INC指定的目錄中尋找文件myfile.pl。如果找到了,該文件中的語句就被執(zhí)行,否則程序終止并輸出錯(cuò)誤信息: ????Can't
find myfile.pl in
@INC ????作為子程序調(diào)用參數(shù),文件中最后一個(gè)表達(dá)式的值成為返回值,require函數(shù)查看其是否為零,若為零則終止。例如myfile.pl最后的語句是: ????print
("hello, world!\n"); ????$var =
0; ????因?yàn)樽詈蟮恼Z句值為零,Perl解釋器輸出下列錯(cuò)誤信息并推出: ????myfile.pl
did not reture true
value ????可以用簡(jiǎn)單變量或數(shù)組元素等向require傳遞參數(shù),如:
@reqlist = ("file1.pl", "file2.pl", "file3.pl"); require
($reqlist[$0]); require ($reqlist[$1]); require ($reqlist[$2]);
????還可以不指定文件名,即: ????require; ????這時(shí),變量$_的值即作為文件名傳遞給require。 ????注:如果@INC中有多個(gè)目錄中含有同一個(gè)文件,則只有第一個(gè)被包含。 1、require函數(shù)和子程序庫 ????用require函數(shù)可以創(chuàng)建可用于所有Perl程序的子程序庫,步驟如下:
a、確定存貯子程序庫的目錄 b、將子程序抽取放到單獨(dú)的文件中,將文件放到子程序庫目錄 c、每個(gè)文件末尾加一句非零值的語句,最簡(jiǎn)單的辦法是語句
1; d、在主程序中用require包含一個(gè)或多個(gè)所需的文件。 e、運(yùn)行主程序時(shí),用 -I
選項(xiàng)指定子程序庫目錄,或者在調(diào)用require前將該目錄添加到@INC數(shù)組中。
????例如:假設(shè)目錄/u/perldir中存有你的Perl子程序庫,子程序mysub存貯在文件mysub.pl中?,F(xiàn)在來包含上該文件: ????unshift
(@INC, "/u/perldir"); ????require
("mysub.pl"); ????對(duì)unshift的調(diào)用把目錄/u/perldir添加到@INC數(shù)組,對(duì)require的調(diào)用將mysub.pl文件的內(nèi)容包含進(jìn)來作為程序的一部分。 注意:
1、應(yīng)該使用unshift來向@INC中添加目錄,而不是push。因?yàn)閜ush增加到@INC的末尾,則該目錄將被最后搜尋。 2、如果你的庫文件名與/usr/local/lib/perl中的某文件同名,則不會(huì)被包含進(jìn)來,因?yàn)閞equire只包含同名文件中的第一個(gè)。
2、用require指定Perl版本 ????Perl
5中,可以用require語句來指定程序運(yùn)行所需的Perl版本。當(dāng)Perl解釋器看到require后跟著數(shù)字時(shí),則只有其版本高于或等于該數(shù)字時(shí)才運(yùn)行該程序。例如,下面語句表明只有Perl解釋器為5.001版或更高時(shí)才運(yùn)行該程序: ????require
5.001; 二、包 ????Perl程序把變量和子程序的名稱存貯到符號(hào)表中,perl的符號(hào)表中名字的集合就稱為包(package)。 1、包的定義 ????在一個(gè)程序中可以定義多個(gè)包,每個(gè)包有一個(gè)單獨(dú)的符號(hào)表,定義語法為: ????package
mypack; ????此語句定義一個(gè)名為mypack的包,從此以后定義的所有變量和子程序的名字都存貯在該包關(guān)聯(lián)的符號(hào)表中,直到遇到另一個(gè)package語句為止。 ????每個(gè)符號(hào)表有其自己的一組變量、子程序名,各組名字是不相關(guān)的,因此可以在不同的包中使用相同的變量名,而代表的是不同的變量。如:
$var = 14; package mypack; $var = 6;
????第一個(gè)語句創(chuàng)建變量$var并存貯在main符號(hào)表中,第三個(gè)語句創(chuàng)建另一個(gè)同名變量$var并存貯在mypack包的符號(hào)表中。 2、在包間切換 ????在程序里可以隨時(shí)在包間來回切換,如:
1: #!/usr/local/bin/perl 2: 3: package pack1; 4: $var =
26; 5: package pack2; 6: $var = 34; 7: package pack1; 8:
print ("$var\n");
????運(yùn)行結(jié)果如下:
$ program 26 $
????第三行定義了包pack1,第四行創(chuàng)建變量$var,存貯在包pack1的符號(hào)表中,第五行定義新包pack2,第六行創(chuàng)建另一個(gè)變量$var,存貯在包pack2的符號(hào)表中。這樣就有兩個(gè)獨(dú)立的$var,分別存貯在不同的包中。第七行又指定pack1為當(dāng)前包,因?yàn)榘黳ack1已經(jīng)定義,這樣,所有變量和子程序的定義和調(diào)用都為該包的符號(hào)表中存貯的名字。因此第八行對(duì)$var的調(diào)用為pack1包中的$var,其值為26。 3、main包 ????存貯變量和子程序的名字的缺省符號(hào)表是與名為main的包相關(guān)聯(lián)的。如果在程序里定義了其它的包,當(dāng)你想切換回去使用缺省的符號(hào)表,可以重新指定main包: ????package
main; ????這樣,接下來的程序就好象從沒定義過包一樣,變量和子程序的名字象通常那樣存貯。 4、包的引用 ????在一個(gè)包中可以引用其它包中的變量或子程序,方法是在變量名前面加上包名和一個(gè)單引號(hào),如:
package mypack; $var = 26; package main; print
("$mypack'var\n");
????這里,$mypack'var為mypack包中的變量$var。 ????注意:在Perl
5中,包名和變量名用雙冒號(hào)隔開,即$mypack::var。單引號(hào)引用的方式仍然支持,但將來的版本中未必支持。 5、指定無當(dāng)前包 ????在Perl
5中,可以用如下語句指定無當(dāng)前包: ????
package; ????這時(shí),所有的變量必須明確指出所屬包名,否則就無效--錯(cuò)誤。 ????
$mypack::var = 21; #ok ???? $var = 21;??
#error - no current
package ????這種情況直到用package語句指定當(dāng)前包為止。 6、包和子程序 ????包的定義影響到程序中的所有語句,包括子程序,如:
package mypack; subroutine mysub { ? local
($myvar); ? # stuff goes here }
????這里,mysub和myvar都是包mypack的一部分。在包mypack外調(diào)用子程序mysub,則要指定包:$mypack'mysub。 ????可以在子程序中切換包:
package pack1; subroutine mysub { ? $var1 = 1; ?
package pack2; ? $var1 = 2; }
????這段代碼創(chuàng)建了兩個(gè)變量$var1,一個(gè)在包pack1中,一個(gè)在包pack2中,包中的局域變量只能在其定義的子程序等語句塊中使用,像普通的局域變量一樣。 7、用包定義私有數(shù)據(jù) ????包最通常的用途是用在含有子程序和子程序所使用的全局變量的文件中,為子程序定義這樣的包,可以保證子程序使用的全局變量不可在其它地方使用,這樣的數(shù)據(jù)即為私有數(shù)據(jù)。更進(jìn)一步,可以保證包名不可在其它地方使用。私有數(shù)據(jù)例:
1 : package privpack; 2 : $valtoprint = 46; 3 : 4 : package
main; 5 : # This function is the link to the outside world. 6 :
sub printval { 7 : ? &privpack'printval(); 8 : } 9
: 10: package privpack; 11: sub printval { 12: ? print
("$valtoprint\n"); 13: } 14: 15: package main; 16: 1; #
return value for require
????此子程序只有在調(diào)用printval后才能產(chǎn)生輸出。 ????該文件分為兩個(gè)部分:與外界聯(lián)系的部分和私有部分。前者為缺省的main包,后者為包privpack。第6~8行定義的子程序printval可被其它程序或子程序調(diào)用。printval輸出變量$valtoprint的值,此變量?jī)H在包privpack中定義和使用。第15、16行確保其被其它程序用require語句包含后工作正常,15行將當(dāng)前包設(shè)置回缺省包main,16行返回非零值使require不報(bào)錯(cuò)。 8、包和系統(tǒng)變量 ????下列變量即使從其它包中調(diào)用,也在main包中起作用:
- 文件變量STDIN, STDOUT, STDERR 和 ARGV
- 變量%ENV, %INC, @INC, $ARGV 和 @ARGV
- 其它含有特殊字符的系統(tǒng)變量
9、訪問符號(hào)表 ????在程序中查找符號(hào)表可用數(shù)組%_package,此處package為想訪問的符號(hào)表所屬的包名。例如%_main含有缺省的符號(hào)表。 ????通常不需要親自查找符號(hào)表。
三、模塊 ????多數(shù)大型程序都分割成多個(gè)部件,每一部件通常含有一個(gè)或多個(gè)子程序及相關(guān)的變量,執(zhí)行特定的一個(gè)或多個(gè)任務(wù)。集合了變量和子程序的部件稱為程序模塊。 1、創(chuàng)建模塊 ????Perl
5中用包來創(chuàng)建模塊,方法是創(chuàng)建包并將之存在同名的文件中。例如,名為Mymodult的包存貯在文件Mymodult.pm中(擴(kuò)展名.pm表示Perl
Module)。下例的模塊Mymodult含有子程序myfunc1和myfunc2及變量$myvar1和$myvar2。
1 : #!/usr/local/bin/perl 2 : 3 : package Mymodule; 4 :
require Exporter; 5 : @ISA = qw(Exporter); 6 : @EXPORT =
qw(myfunc1 myfunc2); 7 : @EXPORT_OK = qw($myvar1 $myvar2); 8
: 9 : sub myfunc1 { 10: ? $myvar1 += 1; 11:
} 12: 13: sub myfunc2 { 14: ? $myvar2 += 2; 15: }
????第3~7行是標(biāo)準(zhǔn)的Perl模塊定義方式。第3行定義包,第4行包含內(nèi)置Perl模塊Exporter,6、7行進(jìn)行子程序和變量的輸出以與外界聯(lián)系。第6行創(chuàng)建名為@EXPORT的特殊數(shù)組,該數(shù)組中的子程序可以被其它程序調(diào)用,這里,myfunc1和myfunc2可以被訪問。其它任何在模塊中定義但沒有賦給數(shù)組@EXPORT的子程序都是私有的,只能在模塊內(nèi)部調(diào)用。第7行創(chuàng)建另一個(gè)名為@EXPORT_OK的特殊數(shù)組,其中含有可被外部程序訪問的變量,這里含有$myvar1和$myvar2。 2、導(dǎo)入模塊 ????將模塊導(dǎo)入你的Perl程序中使用use語句,如下句導(dǎo)入了Mymodule模塊: ????
use
Mymodule; ????這樣,模塊Mymodule中的子程序和變量就可以使用了。 ????取消導(dǎo)入模塊使用no語句,如下句取消了Mymodule模塊的導(dǎo)入: ????
no
Mymodule; ????下面看一個(gè)導(dǎo)入模塊和取消導(dǎo)入的例子,使用integer模塊要求所有數(shù)字運(yùn)算基于整數(shù),浮點(diǎn)數(shù)在運(yùn)算前均被轉(zhuǎn)化為整數(shù)。
1: #!/usr/local/bin/perl 2: 3: use integer; 4: $result = 2.4
+ 2.4; 5: print ("$result\n"); 6: 7: no integer; 8: $result =
2.4 + 2.4; 9: print ("$result\n");
????程序輸出如下:
$ program 4 4.8 $
????如果use或no語句出現(xiàn)在語句塊中,則只在該塊的有效范圍內(nèi)起作用,如:
use integer; $result1 = 2.4 + 2.4; if ($result1 == 4) { no
integer; $result2 = 3.4 + 3.4; } $result3 = 4.4 + 4.4;
????結(jié)果輸出如下:
4 6.8 8
????這里,no語句只在if語句中有效,出了if語句仍使用integer模塊,因此4.4在做加法前被轉(zhuǎn)化成了4。 3、預(yù)定義模塊 ????Perl
5提供了許多有用的預(yù)定義模塊,可以用use導(dǎo)入和no語句取消。下面是庫中最有用的一些模塊:
integer |
使用整數(shù)運(yùn)算 |
Diagnostics ? |
輸出較多的診斷信息(警告) |
English |
允許英文名用作系統(tǒng)變量的別名 |
Env |
導(dǎo)入環(huán)境變量的Perl模塊 |
POSIX |
POSIX標(biāo)準(zhǔn)(IEEE 1003.1)的Perl接口 ? |
Socket |
裝載C語言的套接字處理機(jī)制 |
????Perl文檔中有完整的預(yù)定義模塊列表。 ????注:世界各地的Perl
5用戶寫了許多有用的模塊,CPAN(Comprehensive Perl Archive
Network)的Perl文檔有其完整的列表。關(guān)于CPAN的更多信息見其網(wǎng)址: http://www.perl.com/perl/CPAN/README.html。
|