ShipIt 與 cpan-upload

三年多沒寫 Perl module,很多東西雖然有印象,但實際上都是重新學習...

Brad Fitzpatrick 寫的 ShipIt 配合 Module::Build 超好用的,還可以配合 Git 自動在產生 tarball 時打上 tag...

cpan-upload 則是可以在 CLI 介面直接上傳到 CPANPAUSE,然後過不久後就可以在 CPAN 上面看到新模組了...

不過還是不夠熟練,繼續研究吧...

產生 Perl Module 的工具:Module::Starter

很久以前只知道用 h2xs 產生 Perl 的模組架構,後來被推薦可以用 Module::Starter 產生... (忘記是誰推薦的,找 irc 紀錄沒翻到)

這幾天要用,在 SlideShare 上面找到「Packaging Perl Modules」這份投影片,雖然是 2007 年的投影片,但還是相當實際...

在裝好 Module::Starter 後,先建立 ~/.module-starter 目錄並設定 ~/.module-starter/config

author: Gea-Suan Lin
email: gslin@gslin.org
builder: Module::Build

然後就收工了... 要產生模組時用:

module-starter --module Foo::Bar

生出來的東西會比 h2xs 簡單不少...

Update:結果是 c9s 提醒了:「@gslin module::setup & ShipIt. would help.」。

Perl 的 Object::Destroyer

使用 HTML::Tree 時因為有 circular reference,會要求你要使用 ->delete() 告知 object 打斷 reference 以避免 memory leak。於是就得很小心寫,要注意每個步驟以免某些狀況下忘記 ->delete() 而造成 leak:

my $html = HTML::TreeBuilder->new_from_content($body);
foreach my $element ($html->look_down('a', qr{某個 RE 條件})) {
    if (符合某個條件) {
        # 做某些事情...

        $element->delete;
        $html->delete;
        return;
    }

    # 做某些事情...
    $element->delete;
}
$html->delete;

後來找到了 Object::Destroyer,利用另外一個 object 的存活幫忙回收,於是就可以簡化成:

my $html = HTML::TreeBuilder->new_from_content($body);
my $htmlD = Object::Destroyer->new($html, 'delete');
foreach my $element ($html->look_down('a', qr{某個 RE 條件})) {
    my $elementD = Object::Destroyer->new($element, 'delete');
    if (符合某個條件) {
        return;
    }
    # 做某些事情...
}

這樣就不會 leak 了...

Perl 的 AnyEvent + EV

Coro 用起來不太順,於是跑到 freenode 的 #perl.tw 上問 Coro 是不是能用的東西,結果 clkao 建議了 AnyEvent,用了感覺反而比 Coro 順手,大概是因為平常對 event-based 的東西還算習慣吧...

與「Perl 的 Threading 實做:Coro」這篇同樣的東西,改用 AnyEvent + EV 寫:

Perl 的 Threading 實做:Coro

去年「Perl - PSGI」這篇文章裡面提到 Perl 的 threading 一直是頭痛的問題之一,唐鳳在留言上推薦用 Coro 而非原來的 thread。

實際測試後發現並非 OS level 的 threading,而是利用抽換的方式將系統內許多 blocking function 換掉,並且支援常用到的 module (像是 libwww-perl 系列),使得現有的程式要 porting 到 Coro 上會簡單很多,寫起來也的確比較像 threading 程式。(雖然實做比較接近 event-based)

附上之前寫來測試的程式,用的是 PIXNETAPI

Perl 5.8 升級至 Perl 5.10

FreeBSD 前陣子才將 Perl 5.10 放入 FreeBSD Ports System 內 (Perl 5.10 在 2007/12/18 發行,到 2009 年三月才進 ports...)

不管怎麼樣,總是進 ports 了... 得測試看看要怎麼從 5.8.9 升級到 5.10.0。在 /usr/ports/UPDATING 提供了 portupgradeportmaster 的升級方式:

20080328:
  AFFECTS: users of lang/perl*
  AUTHOR: skv@FreeBSD.org

  lang/perl5.10 is out. If you want to switch to it from, for example
  lang/perl5.8, that is:

  Portupgrade users:
    0) Fix pkgdb.db (for safety):
        pkgdb -Ff

    1) Reinstall perl with new 5.10:
        portupgrade -o lang/perl5.10 -f perl-5.8.\*

    2) Reinstall everything that depends on Perl:
        portupgrade -fr perl

  Portmaster users:
        portmaster -o lang/perl5.10 lang/perl5.8
        portmaster -r perl\*

原則上照著 UPDATING 做就可以,不過 portmaster 的部份似乎是錯的 (看起來是軟體 bug),用 -r 並不會將相依 perl-5.10.0 的 ports 強制更新。

後來還是先 portmaster -BDuw p5\*,然後再看還有哪些東西在 /usr/local/lib/perl5/site_perl/5.8.9 下面,手動跑 portmaster 重新安裝。

Perl on Google App Engine

Python 是第一個可以在 Google App Engine (GAE) 上執行的程式語言,而下一個很有可能是 Perl

Brad Fitzpatrick 在他的 Blog 上說,他被 GAE team 允許對外公佈「我可以使用 20% 的時間開發 Perl on GAE」:Perl on App Engine

這是 GAE 支援其他程式語言的消息中,第一個被正式公開的。在 Brad Fitzpatrick 的文章裡面有一些藍圖,關於他大概會怎麼做的想法。我們應該可以期待他認真起來的戰鬥力 :p

PS:Brad Fitzpatrick 是 LiveJournal 的創辦人、memcached 的作者、OpenID 的制定人。

Perl 5.10.0

上一堆 ports maintainer 要傷腦筋處理 5.8 與 Perl 5.10 之間的相容性問題了...

Perl 5.10.0 除了修正 bug 外,在效率上也做了許多改進,在 可以查到完整的內容,幾個我比較有興趣的:

  • 引入 // 運算子。以前寫 defined $a ? $a : $b,現在可以寫 $a // $b。同理,$a //= $b 等價於 $a = (defined $a ? $a : $b),表示 $a 沒有被定義時塞入 $b。另外,//|| 有相同的優先權。
  • 有了 switch-case-default 的架構,不過在 Perl 裡叫 given-when-default
  • 更快的 Regular Expression Engine,以及一些變動。
  • Perl 內建的 資料庫更新到 5.0.0。
  • 新增了一堆 module...
  • 一堆效能的改善...

反正用就是了 XD

對了,大力推薦 ,試圖在 Win32 平台上建立一個簡單而且強大的 Perl 環境,目前還是 Perl 5.8.8,等他正式推出 Perl 5.10.0 的版本...

如果要測試的人可以參考 這篇抓 Beta 2 版測試。

Update:除了上面所說的,另外還有 提到的 say (與 print + \n) 以及 ~~ (與 grep + eq) 的效能比較。

Update 5.10.0 正式出版了!

Perl 與 Python 在 Unicode 的處理

我試著在 上找到 Perl Regular Expression 有提供的 General Category Property,不過沒有找到。而且發現 沒有使用

先參考 上的文件, 這篇,在 Regular Expression 裡使用 General Category Property 指的是 \p{Lu} 這種用法,前面的範例表示大寫字母 (Uppercase Letter),我在用 切詞的時候用了兩次這種 Regular Expression。

替代的方案是依照 裡的說法去找對應的範圍,然後自己寫 Regular Expression。

Update 比較清楚,直接把 Hex Start 與 Hex End 列出來。