Perl 包和模組

Perl 包和模組

Perl 中每個包有一個單獨的符號表,定義語法為:

package mypack;

此語句定義一個名為 mypack 的包,在此後定義的所有變數和子程式的名字都存貯在該包關聯的符號表中,直到遇到另一個 package 語句為止。

每個符號表有其自己的一組變數、子程式名,各組名字是不相關的,因此可以在不同的包中使用相同的變數名,而代表的是不同的變數。

從一個包中訪問另外一個包的變數,可通過" 包名 + 雙冒號( :: ) + 變數名 " 的方式指定。

存貯變數和子程式的名字的預設符號表是與名為 main的包相關聯的。如果在程式裡定義了其它的包,當你想切換回去使用預設的符號表,可以重新指定main包:

package main;

這樣,接下來的程式就好象從沒定義過包一樣,變數和子程式的名字象通常那樣存貯。

以下例項中檔案有 main 和 Foo 包。 特殊變數 __PACKAGE__ 用於輸出包名:

例項

#!/usr/bin/perl # main 包 $i = 1; print "包名 : " , __PACKAGE__ , " $i\n"; package Foo; # Foo 包 $i = 10; print "包名 : " , __PACKAGE__ , " $i\n"; package main; # 重新指定 main 包 $i = 100; print "包名 : " , __PACKAGE__ , " $i\n"; print "包名: " , __PACKAGE__ , " $Foo::i\n"; 1;

執行以上程式,輸出結果為:

包名 : main 1
包名 : Foo 10
包名 : main 100
包名: main 10

BEGIN 和 END 模組

Perl語言提供了兩個關鍵字:BEGIN,END。它們可以分別包含一組指令碼,用於程式體執行前或者執行後的執行。

語法格式如下:

BEGIN { ... }
END { ... }
BEGIN { ... }
END { ... }
  • 每個 BEGIN 模組在 Perl 指令碼載入和編譯後但在其他語句執行前執行。

  • 每個 END 語句塊在直譯器退出前執行。

  • BEGINEND 語句塊在建立 Perl 模組時特別有用。

如果你還不大理解,我們可以看個例項:

例項

#!/usr/bin/perl package Foo; print "Begin 和 Block 例項\n"; BEGIN { print "這是 BEGIN 語句塊\n" } END { print "這是 END 語句塊\n" } 1;

執行以上程式,輸出結果為:

這是 BEGIN 語句塊
Begin 和 Block 例項
這是 END 語句塊

什麼是 Perl 模組?

Perl5 中用Perl包來建立模組。

Perl 模組是一個可重複使用的包,模組的名字與包名相同,定義的檔案字尾為 .pm

以下我們定義了一個模組 Foo.pm,程式碼如下所示:

例項

#!/usr/bin/perl package Foo; sub bar { print "Hello $_[0]\n" } sub blat { print "World $_[0]\n" } 1;

Perl 中關於模組需要注意以下幾點:

  • 函式 requireuse 將載入一個模組。

  • @INC 是 Perl 內建的一個特殊陣列,它包含指向庫例程所在位置的目錄路徑。

  • requireuse 函式呼叫 eval 函式來執行程式碼。

  • 末尾 1; 執行返回 TRUE,這是必須的,否則返回錯誤。


Require 和 Use 函式

模組可以通過 require 函式來呼叫,如下所示:

例項

#!/usr/bin/perl require Foo; Foo::bar( "a" ); Foo::blat( "b" );

也可以通過 use 函式來引用:

例項

#!/usr/bin/perl use Foo; bar( "a" ); blat( "b" );

我們注意到 require 引用需要使用包名指定函式,而 use 不需要,二者的主要區別在於:

  • 1、require用於載入module或perl程式(.pm字尾可以省略,但.pl必須有)
  • 2、Perl use語句是編譯時引入的,require是執行時引入的
  • 3、Perl use引入模組的同時,也引入了模組的子模組。而require則不能引入,要在重新宣告
  • 4、USE是在當前預設的@INC裡面去尋找,一旦模組不在@INC中的話,用USE是不可以引入的,但是require可以指定路徑
  • 5、USE引用模組時,如果模組名稱中包含::雙冒號,該雙冒號將作為路徑分隔符,相當於Unix下的/或者Windows下的\。 如:

    use MyDirectory::MyModule

通過新增以下語句 use 模組就可以從模組中匯出列表符號:

require Exporter;
@ISA = qw(Exporter);

@EXPORT陣列包含預設匯出的變數和函式的名字:

package Module;

require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(bar blat);  # 預設匯出的符號

sub bar { print "Hello $_[0]\n" }
sub blat { print "World $_[0]\n" }
sub splat { print "Not $_[0]\n" }  # Not exported!

1;

建立 Perl 模組

通過 Perl 分發自帶的工具 h2xs 可以很簡單的建立一個 Perl 模組。

你可以在命令列模式鍵入 h2xs 來看看它的引數列表。

h2xs 語法格式:

$ h2xs -AX -n  ModuleName

引數說明:

  • -A 忽略 autoload 機制

  • -X 忽略 XS 元素

  • -n 指定擴充套件模組的名字

例如,如果你的模組在 Person.pm 檔案中,使用以下命令:

$ h2xs -AX -n Person

執行以上程式將輸出:

Writing Person/lib/Person.pm
Writing Person/Makefile.PL
Writing Person/README
Writing Person/t/Person.t
Writing Person/Changes
Writing Person/MANIFEST

Person 目錄下你可以看到新增加的目錄及檔案說明:

  • README :這個檔案包含一些安裝資訊,模組依賴性,版權資訊等。

  • Changes :這個檔案作為你的專案的修改日誌(changelog)檔案。

  • Makefile.PL :這是標準的 Perl Makefile 構造器。用於建立 Makefile.PL 檔案來編譯該模組。

  • MANIFEST :本檔案用於自動構建 tar.gz 型別的模組版本分發。這樣你就可以把你的模組拿到 CPAN 釋出或者分發給其他人。它包含了你在這個專案中所有檔案的列表。

  • Person.pm :這是主模組檔案,包含你的 mod_perl 控制代碼程式碼(handler code)。

  • Person.t :針對該模組的一些測試指令碼。預設情況下它只是檢查模組的載入,你可以新增一些新的測試單元。

  • t/ :測試檔案

  • lib/ :實際原始碼存放的目錄

你可以使用 tar (Linux 上) 命令來將以上目錄打包為 Person.tar.gz。


安裝 Perl 模組

我們可以對剛才壓縮的 Person.tar.gz 檔案進行解壓安裝,執行步驟如下:

tar xvfz Person.tar.gz
cd Person
perl Makefile.PL
make
make install

首先執行 "perl Makefile.PL" 在當前目錄生成 Makefile;

然後執行 "make" 編譯並建立所需的庫檔案;

之後用 "make test" 測試編譯結果是否正確;最後執行 "make install" 將庫檔案安裝到系統目錄,至此整個編譯過程結束。