幾個使用 LWP (WWW::Mechanize) 的好習慣...

WWW::Mechanize 是繼承 libwww-perl 中 LWP::UserAgent 的工具,所以這個方式通用於兩者...

首先是在取得資料時加上 Accept-Encoding: gzip 的 header,這可以在產生物件時指定,之後就都會送出:

my $ua = LWP::UserAgent->new;
$ua->default_header('Accept-Encoding' => 'gzip');

取回後直接透過 HTTP::Response 的 decoded_content 幫你處理:

my $res = $ua->get($uri);
my $msg = $res->decoded_content;

取回的 $msg 會是 Perl internal encoding,要變成 UTF-8 還需要透過 Encodeencode('utf8', $msg)

這樣只要 server-side 有支援 gzip 就會自動壓縮並且在本地端解開,沒壓縮也沒關係,HTTP::Response 會依照 Content-Type 處理。

Updateclkao 指出 WWW::Mechanize 預設值就會包括 gzip 設定,剛剛拿 code.jquery.com 測試沒錯。

Twitter 轉 Plurk 的程式...

程式在這裡,用 Perl 寫的,讀 Twitter 的 RSS feed 然後丟上 Plurk

另外裡面用到的 SQLite schema 是:

CREATE TABLE entry (id INTEGER PRIMARY KEY AUTOINCREMENT, guid VARCHAR, updated BOOLEAN);

其中 updated 欄位是沒用到的,但我暫時懶的改了...

btw,寫這個程式讓我對 Plurk 的資安感覺到絕望 XD

在 Perl 裡用 LWP::UserAgent (以及繼承它的模組) 時使用 HTTPS 連線處理 CA 認證...

libwww-perl 裡的 LWP::UserAgent 可以處理 HTTPS,並利用 CA 驗證 public key 是否簽過。在 FreeBSD 下安裝 ca_root_nss 後可以在 /usr/local/share/certs/ 下看到檔案,於是可以這樣用:

#!/usr/bin/env perl
use strict;
use warnings;
use LWP::UserAgent;

INIT {
    my $ua = LWP::UserAgent->new;
    $ua->ssl_opts(SSL_ca_file =>
        '/usr/local/share/certs/ca-root-nss.crt');

    my $res = $ua->get('https://mail.google.com/mail/');
    print $res->content;
}

Debian 或是 Ubuntu 下則是透過 ca-certificates 裝到 /etc/ssl/certs/ 下,並且分成很多檔案,這時候本來的 ssl_opts 就要改成 SSL_ca_path => '/etc/ssl/certs/';

PS:FreeBSD 上因為是單檔,依照 SSL_CTX_load_verify_locations(3) 這邊的說明,沒辦法用 CApath...

CPAN 官方支援 Syntax Highlighter...

剛剛看到 CPAN 網站上直接由官方支援 Syntax Highlighter:Syntax highlighting for search.cpan.org,雖然目前的 UI 做的並不太好 (選擇 theme 的選擇條應該是上下都要有,目前只有最下方),但仍然是進步不少...

之前的 Greasemonkey script 在 Firefox 4.0 上爛掉 (因為 async loading 的關係),本來還在想要怎麼處理,現在看起來就用官方提供的就好了...

多使用 namespace::clean 與 namespace::autoclean

純粹實際驗證用:

因為 Carp 預設會將一些函式 export 到現有的 namespace 下,如果不使用 namespace::clean 或是 namespace::autoclean 這類工具幫你清除,會造成 namespace 與 object 內帶有這些函式。

結果是:

可以看到沒有 B 沒有 clean 導致外面 (package main) 可以看到 carp

其實這篇是要測 pastie 是不是比 Gist 好用... :o

加速 Perlbrew 安裝 Perl 的速度

Perlbrew 0.18 其中一項很重要的功能,是在 install perl 時可以使用 -j 的參數,像是這樣:

perlbrew --force install -j 4 perl-5.12.3

-j 這個參數會傳給 make,同時跑的 job 數量。(make 會處理 dependency 問題,理論上不會有問題)

Linode 512 上面 (Debian 64bits) 只用了 7 分鐘就把 Perl 5.12.3 裝完了 (之前是 21 分鐘),時間就是金錢啊... 細節可以參考 0.18 的 Changes 的說明。

非 root 環境下的 App::perlbrew 與 App::cpanminus

跟 gugod 討論後發現我之前所寫的方式有問題,所以重寫一篇...

首先是安裝 App::perlbrew 的方式:

wget --no-check-certificate http://xrl.us/perlbrew
chmod a+x perlbrew
./perlbrew install
./perlbrew init

這樣在自己的目錄下就會有 perlbrew 了,接下來是設定環境變數:

source ~/perl5/perlbrew/etc/cshrc # (for csh/tcsh)
source ~/perl5/perlbrew/etc/bashrc # (for bash)

並將自己的 ~/.cshrc 或是 ~/.bashrc 裡加入上面的 source 指令。

原來下載的 perlbrew 就可以砍掉了,然後把 Perl 5.12.3 的環境建好:

rm perlbrew
perlbrew install perl-5.12.3
perlbrew switch perl-5.12.3

接著是用 App::cpanminus (standalone) 安裝 App::cpanminus (套件):

wget --no-check-certificate -O cpanm http://cpanmin.us/
chmod a+x cpanm
./cpanm -n App::cpanminus

然後一樣把下載下來的 cpanm 砍掉:

rm cpanm

這樣可以在不碰到「CPAN」這個大模組的情況下,把基本的系統裝好...

App::perlbrew 另外的裝法

Update:這篇內容有問題,請參考「非 root 環境下的 App::perlbrew 與 App::cpanminus」這篇新的說明。

App::perlbrew 的說明,在系統已經有 Perl 的情況下,不需要先用 CPAN 裝 App::perlbrew,可以直接抓 App::perlbrew 的執行檔:

wget --no-check-certificate http://xrl.us/perlbrew 或是
curl http://xrl.us/perlbrew > perlbrew

其中 wget 要加上 --no-check-certificate 是因為檔案實際是放在 GitHub 上,而 GitHub 目前是強制 HTTPS。

接下來直接執行 perlbrew 相關的指令,通常就是:

chmod 755 perlbrew
./perlbrew init
./perlbrew install perl-5.12.3
./perlbrew switch perl-5.12.3

後面的就跟之前提到的一樣了。這樣要建立自己的 Perl 環境就更簡單了...

Markapl:Markup as Perl

Markaplgugod 寫的 Perl module,這是在 miyagawa (宮川達彦) 的 Sunaba 模組上看到的... 以 Perl 的語法建立 HTML。

目前 CPAN 上面 Markapl 的不是最新版 (0.11),在 GitHub 上的 Markapl 比較新... (據說是作者忘記在 release 0.11 後有 commit 了,在寫這篇文章的時候已經 release 新版,等下應該就會看到了...)

至於範例... 直接參考 Sunaba 的 View.pm 會比較快。(我故意連到特定版本,避免之後改動架構這個檔案被搬走。目前版本的 View.pm 請點這個連結)

用 Markapl 除了可以用 Perl 語法外,另外一個「好處」是強迫自己將 css 與 javascript 搬到 template 外面,因為 template 內實在是不好寫... (用「q/.../」?用「<<CSS;」然後「CSS」結尾?gosh XD)

另外補充一點,範例上都沒有 DOCTYPE,請用「outs_raw('<doctype html>');」加在 html 前即可。