回到首頁過去文章最新消息FAQ相關討論 | 關於我們

Contributing to Comprehensive Perl Archive Network (CPAN)


大家好,這期本來應該要將 dll 講完,不過 YAPC 到了,趁這個時候來為 Perl 打個 廣告,所以本期談的是 Perl 綜合典藏網 (Comprehensive Perl Archive Network), 簡稱 CPAN 。

雖然說是談 CPAN,不過這裡不會介紹什麼是 CPAN,它的由來、歷史沿革等等。我們 今天只要知道,我如果寫了一個 Perl 模組,我要怎麼經由 CPAN 提供給世界各地的人 利用。

首先,CPAN 的網址為 http://www.cpan.org/,不過我個人推薦的是另一個網址: http://search.cpan.org/,那麼我們就由後者開始講起。你連上去看到的頁面應該是 英文,如果不是的話請重新再連線一次,上面為 Perl 模組的分類。你要嘛可以由這 些分類點下去看看,要嘛也可以直接在上面的 Textbox 做搜尋。

搜尋什麼呢?

如果你對於 Perl 小有認識,也許你曾經在 Perl 程式碼中看過:

 use Encode;
 use DBI; 

等等,這些的 ”use ‥‥;” 就是告訴 Perl 你這個程式有需要某些模組的幫忙, 所以要先行宣告一下。而今天我們要來做的就是模組,讓一些功能不必被重複開發, 那上週剛好寫了一個新的套件,就拿它來做示範。

進入 CPAN 的第一步,就是要申請 CPAN 的帳號,完全免費、提供 @cpan.org 的郵件 帳號,而且,就算不上傳任何模組也沒關係。有沒有這麼好的事呀!當然我們是要來 進貢的,怎麼可以只吃不做事呢。

PAUSE 一下吧,這裡的 PAUSE 是 The Perl Authors Upload Server 的意思,也就是 讓 Perl 作者們上傳檔案的地方囉。網址在 http://pause.perl.org/。 若你已經有帳號了,當然可以跳過這一部份,若你沒有,那麼這時候該做的事就是申 請帳號,點選左方的”Request PAUSE account”,照著上面的指示填入正確的資料, 在”Full name”的地方可以打中文沒關係,它是顯示 UTF-8 資料的。

好了,下一步就是登入 PAUSE,鍵入帳號密碼之後可以發現左方的項目變多了,因為 今天只是要來上傳檔案,其他的就不介紹了。請點選”Upload a file to CPAN”, 看到了嗎?就是這個頁面,你有什麼模組,就是從這裡上傳。當然,也許你會覺得 每次上傳都要經過這麼麻煩的程序,不太高興。沒關係,我們來看看別人發展的輪子 ,”cpan-upload”就是拿來做這些事的,使用方法很簡單,語法如下:

 % cpan-upload Lingua-ZH-Segment.tar.gz 

就可以完成一切的動作了,當然第一次執行的時候會問你一些基本的問題,不過你只 要記得,想省麻煩,用它就對了。FreeBSD 的使用者,可以到 ports 下的 devel/cpan-upload 安裝,其他作業系統的使用者,抱歉啦!我想一定有一樣簡單的 方法的:

(FreeBSD 4.x/5.x)
% cd /usr/ports/devel/cpan-upload
% make install clean
% cpan-upload 
...(回答問題、一勞永逸)

再回來談套件模組吧,有了食譜,怎麼能沒有料呢!坊間不論是網頁或是書籍,談到 的方式大概都不出 manpages(perlmodlib、perlmodstyle、perlnewmod)裡提的方 法,除了一個一個檔案刻程式碼上去,再不然也可以用一些好用的工具 (module-starter、h2xs 等等)。module-starter 可以由安裝 Module::Starter 而來,啊不過剛剛找一下沒看到在 FreeBSD ports tree 裡,沒關係,YAPC 之前我 就會把它送進去了。
而我提供一個比較快速,只不過大家平常比較不敢公開講的方法。沒錯!就是 CP大法,沒有什麼比直接拿別人的來改還要快的,尤其是初學者如我。為了避免一些 你我也不知道錯在哪裡的錯誤,最快速的方法當然就是拿成功案例來用囉。 改改改、傳傳傳,就大功告成了。
當然,就算是抄作業也要自己做點功課,這裡的建議是,先看看有沒有人做出同樣功能 的模組(去 CPAN 搜尋),有的話就直接使用啦,犯不著跟別人過不去 :p 沒有的話,找個功能相近,起碼也是在同一個目錄下的模組,這樣要改的東西會少很多 ,當然也不要找個太大的模組。

% tar zxpf XXX-YYY.tar.gz
% cp -R XXX-YYY/ XXX-ZZZ/
% cd XXX-ZZZ/

一切就緒之後,注意一下你需要改哪些檔案?以下舉出一些民生必需品:

  • README -> 對於這個套件你想說的話
  • Changes 或是 ChangeLog -> 版本沿革,總是要讓別人知道你改了什麼吧!
  • Makefile.PL 或是 Build.PL -> 就像是 Makefile ,要做的事就列在裡面
  • MANIFEST -> 裡面會列出套件中有哪些檔案,這個可以由 make manifest 自動產生
  • lib/ -> 這就是放你的模組的地方囉
  • t/ -> 測試程式區,打 make test 後就會執行裡面的測試句,用來自行測 程式是不是能達成你要的功能

其他的就不是那麼重要,先不管。
現在,我們以 Lingua-ZH-Segment 這個模組來做示範,告訴大家我是如何偷工減料地佔 CPAN 一個套件的空間。
一開始是為了要找一個簡單的斷詞元件,將中文與英文分離,同時中587;要能夠變成以字 為單位。而有一個類似的模組:Lingua-ZH-Toke,幾乎可以做到一樣的事,甚至功能更 強,不過它是依賴 libtabe (http://libtabe.sourceforge.net/,一個很好用的中文 處理工具)。我想想,沒有必要為了一個小功能搬來這麼大一個輪子,所以才想要自己 寫,何況自己寫有個好處是,可以做出自己本來就想要的功能而非妥協(當然,別人要 用就要看看是不是需要做某些修改囉)。廢話這麼多,不像我,所以趕快來看程式吧!
CP大法的第一招是改名,類似上面寫的:

% tar zxpf Lingua-ZH-Toke-0.02.tar.gz
% mv Lingua-ZH-Toke Lingua-ZH-Segment (當然是先決定你要做什麼囉)
% cd Lingua-ZH-Segment
% mv lib/Lingua/ZH/Toke.pm lib/Lingua/ZH/Segment.pm

再來改改 README、Changes,這兩個檔就沒什麼特別要介紹的了,大家看多了自然就知 道要寫些什麼啦!
比較要緊的是 Makefile.PL,以及剛剛改的 Segment.pm,另外還有 t/ 下面的測試檔, 因為我腳剛剛受傷的關係,暫時就不先介紹 t/ 的寫法了,留待之後介紹 Perl 模組時 再一併講解囉(我是不是愈欠愈多啦?)反正這些東西都可以在 CPAN 上找到。 URL:http://search.cpan.org/~clsung/Lingua-ZH-Segment/

Makefile.PL:

     1	use inc::Module::Install;
     2	
     3	name('Lingua-ZH-Segment');
     4	author('Cheng-Lung Sung ');
     5	abstract('Simple Segmentation of Chinese Text');
     6	license('perl');
     7	version_from('lib/Lingua/ZH/Segment.pm');
     8	
     9	requires(qw(
    10	    perl        5.8.1
    11	    Test::More  0
    12	));
    13	
    14	WriteAll( );

好的,你只要看3∼12行,前後兩行不用管它,照著用就對了,首先是表明你這個 套件的名稱,再來是介紹誰是作者,以及這個套件的摘要簡介(3∼5)。而 license('perl') 表示這個套件所使用的 license 是 Perl ,詳細有哪些 license 可以去 CreativeCommons 看看(http://creativecommons.org/)。再來是表示套件 版本是由哪而來,因為目前只有一個模組,所以顯而易見地當然是填上該模組的相對 路徑。
9∼12行說明了要成功建置這個套件所需要的額外模組,因為我的程式用到了 Encode::Guess,所以至少也要是 perl 5.8.x 才能自由運用,而我在 t/ 下的測試 程式也用到了 Test::More 模組,所以這裡一併寫上, 0表示我沒有對該模組的版本 有特別的要求。
好啦,再來看看 Segmenet.pm,基本上就是一堆夾雜程式碼及說明的檔案,請各位直 接到 CPAN 上看就可以了。這裡摘要一下:

     1	use Encode::Guess;
     2	our @ISA    = qw(Exporter);
     3	our @EXPORT = qw(segment);
     4	our $VERSION    = '0.01';

use Encode::Guess 表示你要用到別人的輪子囉,要先拜個碼頭,不然就用不了囉。 要注意的地方就是 our @EXPORT = qw(...); 的地方,這裡記載了你想要讓別人使用 的函式。而 our $VERSION 就是註明本模組的版本,同時也是這個套件的版本(上面 才剛說過的)。
而在 =cut 之後就是核心的程式碼, sub segment {...},裡面的程式碼有空再做介 紹,因為一方面簡單,二方面這不是重點。只要記得它可以處理 big5/utf8 的中文 斷詞就好了。
編完之後,要怎麼測試呢?依照 Perl 的 SOP:

% perl Makefile.PL
% make
% make test

要是沒有任何 fail,那麼就恭喜你,可以上傳囉。

% perl Makefile.PL 
Writing META.yml
Writing Makefile for Lingua::ZH::Segment
% make 
cp lib/Lingua/ZH/Segment.pm blib/lib/Lingua/ZH/Segment.pm
Manifying blib/man3/Lingua::ZH::Segment.3
% make test
PERL_DL_NONLAZY=1 /usr/local/bin/suidperl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'inc', 'blib/lib', 'blib/arch')" t/*.t
t/0-basic........ok                                                          
t/1-utf8words....ok                                                          
t/2-big5words....ok                                                          
All tests successful.
Files=3, Tests=4,  1 wallclock secs ( 0.34 cusr +  0.13 csys =  0.47 CPU)

上傳之前,要先做一個 .tar.gz 檔,用的指令是”make dist”:

% make dist

最後使用 cpan-upload 上傳,就大功告成囉!

% cpan-upload Lingua-ZH-Segment-0.01.tar.gz

下回見!