
Perl界でじわじわもりあがってきてるMVCウェブフレームワーク Catalyst を試してみた。
Catalyst は Maypole というフレームワークの後継らしい。MaypoleのページのCatalystの説明によると、
Catalyst is a new, elegant web application framework for Perl. It is based on Maypole and adds many features from Ruby-on-Rails, Struts, Spring and Tomcat in a new and innovative way.
と言われていて、いろいろな既存プロジェクトからエッセンスをもらったフレームワークなんだね。
こいつの大きな特徴は、いくつかのコマンドを打つだけでアプリの原型(スケルトン)を作成してくれること。しかも TT や Class::DBI、Ajax なJavaScript などもプラグインで対応していて、同じフレームワークである Sledge や CGI::Application よりもモダンな印象をうける。後述するAttributeを使ったアクション定義や、テストサーバー機能もクールです。
以下、作業メモ。
試したのは PowerbookG4(10.3.9)。CPAN で一式をインストールします。つい先日 HD を初期化した後だったというのもあるけど、大量に関連モジュールを入れてくれました。
% sudo perl -MCPAN -e shell
install Bundle::Catalyst
追記:最近ちょっと違う。こちらを参照されたし
たりないモジュールがあればあとで入れるとして、とりあえず進む。
まず、作業ディレクトリで catalyst.pl をたたきます。
$ catalyst.pl Hello ← 引数でアプリのPackage名を指定。ディレクトリを切る場合はTomi::Hogeとか。
created "Hello" ← そのPackage名でフォルダを作ってくれます
created "Hello/script"
created "Hello/lib"
created "Hello/root"
created "Hello/t"
created "Hello/t/M"
created "Hello/t/V"
created "Hello/t/C"
created "Hello/lib/Hello"
created "Hello/lib/Hello/M"
created "Hello/lib/Hello/V"
created "Hello/lib/Hello/C"
created "Hello/lib/Hello.pm" ← これがコントローラ
created "Hello/Build.PL"
created "Hello/Makefile.PL"
created "Hello/README"
created "Hello/Changes"
created "Hello/t/01app.t"
created "Hello/t/02pod.t"
created "Hello/t/03podcoverage.t"
created "Hello/script/hello_cgi.pl" ← このへん、専用のヘルパースクリプト
created "Hello/script/hello_fastcgi.pl"
created "Hello/script/hello_server.pl"
created "Hello/script/hello_test.pl"
created "Hello/script/hello_create.pl"
追記:最近は M、V、C でなくて Model、View、Controller となります。
あとは MVC をそれぞれ作成していくのだけど、Catalyst の売りである Class::DBI とか Template との連携などはヘルパースクリプトを利用してお決まりのものを作らせてしまうのが Catalyst 流。ビューで Template-Toolkit を使う場合はこんな感じ。
$ cd Hello ← 作成されたディレクトリに移動
$ script/hello_create.pl view TT TT ← ビューを作成、TTというクラス名で、TTを利用するの意
created "/Users/sherlock/Sites/public_html/cata/Hello/script/../lib/Hello/V/TT.pm"
created "/Users/sherlock/Sites/public_html/cata/Hello/script/../t/V/TT.t"
ほかにも、help をみるといろんなことができるらしい。
$ script/hello_create.pl -help
Usage:
hello_create.pl [options] model|view|controller name [helper] [options]
Options:
-help display this help and exits
Examples:
hello_create.pl controller My::Controller
hello_create.pl view My::View
hello_create.pl view MyView TT
hello_create.pl view TT TT
hello_create.pl model My::Model
hello_create.pl model SomeDB CDBI dbi:SQLite:/tmp/my.db
hello_create.pl model AnotherDB CDBI dbi:Pg:dbname=foo root 4321
See also:
perldoc Catalyst::Manual
perldoc Catalyst::Manual::Intro
Hello/lib/Hello.pm をカスタマイズしていきます。POD ドキュメントを消してみるとこんな感じのシンプルなコントローラです。
package Hello;
use strict;
use Catalyst qw/-Debug/;
our $VERSION = '0.01';
Hello->config( name => 'Hello' );
Hello->setup;
sub default : Private {
my ( $self, $c ) = @_;
$c->res->output('Congratulations, Hello is on Catalyst!');
}
1;
部位ごとの説明。
まず、4行目の use Catalyst 部について。
渡すオプションによって、Catalystの基本機能を決定します。ハイフン付きのものはオプション指定で、ついてないのは利用するプラグイン。例えば、デバッグオプションがONで、Catalyst::Plugin::FormValidator を使うぞという時はこうする。
use Catalyst qw(
-Debug
FormValidator
);
今回は -Debug オプションしか使わない。
次に、8行目のconfig設定部について。
ここには、ハッシュの形で好きなものを登録でき、それはコントローラ内のサブルーチンから参照できます。たいていは TT で利用するグローバルな変数とかテンプレートのパスとかを設定。今回はとりあえずそのまま。
Hello->config(
name => 'Hello',
);
12行目以下には、コントローラを記述していく。
つまりアクセス URL 形式とサブルーチンを対応させるのだけど、コントローラというのが「属性」を付けた複数のサブルーチンというのが Catalyst の面白いところ。
たとえば、http://パス/hogehoge/ という形式でアクセスされたときに実行したい処理は、以下のように記述する。
sub hogehoge : Global {
# 処理...
}
パスと処理のマッピングを XML などの別ファイルにしないところがいかにもPerl的な気がする。 関数もしくは変数 : 属性 という、あまり利用されていないけどちゃんと予約されている正規の構文を使ってくるあたりもヒジョーにマニアックでよいです。
この 関数名 : 属性 の指定方法には以下のようなものがあります。
リクエストパス系
| 関数名 : 属性 | 意味 |
|---|---|
| aaaaa : Global | その関数名でアクセスされた場合に内容を実行。 例だとhttp://パス/aaaaa/の時に実行。関数名部分は何でもよい。ただし当然ながらURLとして問題ないものに限る。URLのPATHINFO部分もPerlの関数名も大文字小文字を区別するので、AaaとaaAは異なる。 |
| eeeee : Regex('^step\d$') | Globalに似てるが、リクエストパスを正規表現で指定。 例だとhttp://パス/step1/とかhttp://パス/step2/で実行される。関数名部分は自由。 |
リクエストパスに一致する関数が複数指定指定されていた場合、上のもの一つだけ実行されるみたいです。
デフォルト処理系
| 関数名 : 属性 | 意味 |
|---|---|
| default : Private | どれにも一致しないリクエストパスの場合呼び出されるデフォルト処理関数。トップページの処理など。 |
| begin : Private | 指定した場合、すべてのリクエストパス系処理の最初に必ず呼び出される |
| auto : Private | 指定した場合、すべてのリクエストパス系処理の最初に必ず呼び出される(beginの後) |
| end : Private | 指定した場合、すべてのリクエストパス系処理の最後に必ず呼び出される |
さてつぎに、サブルーチン内処理ですが、
sub default : Private {
my ($self, $c) = @_;
$c->res->output('Hello');
}
みたいにして、第二引数で入ってくる $c を利用して Catalyst のオブジェクトを操作。詳しくはみてないけどよく使うのは以下のようなもの。
| $c | 内容 |
|---|---|
| $c->config | 設定値へのハッシュリファレンス。$c->config->{'name'}; などとしてアクセス |
| $c->stash | オブジェクト間で利用する変数格納用ハッシュリファレンス。$c->stash->{'message'} = "こんにちは!"; などとしておいてほかのオブジェクトから利用 |
| $c->req->param | GET・POSTの値へのハッシュリファレンス。$c->req->param('zip'); などとしてアクセス |
| $c->req->arguments | PATHINFOをスラッシュで区切ったリストリファレンス。http://パス/hoge/a/b/c/ のとき $c->req->arguments->[1] は b |
| $c->req->snippets | 実行サブルーチンの属性がRegexで、正規表現内でメモリかっこを利用した場合、結果が入るリストリファレンス。hoge : Regex('^step(\d+)$') のとき http://パス/step50/ でアクセスすると $c->req->snippets->[0] は 50 |
| $c->res->output |
引数をそのまま出力。$c->res->output('Hello!'); など
|
| $c->res->redirect | 引数にリダイレクト。$c->res->redirect('/'); など |
| $c->res->content_type |
$c->res->content_type("text/html; charset=EUC-JP"); など
|
| $c->res->forward | ほかのサブルーチン・オブジェクトに処理を投げる。$c->res->forward('hoge'); など。Template-Toolkitを利用するにはstashを利用して、
$c->stash->{template} = 'page2.html';
$c->forward('Hello::V::TT');
のようにする。
|
| $c->log | $c->log->debug("message!"); とするとログに文字を吐ける。 |
以上をふまえて、 1)まずシンプルに Hello と page2/ へのリンクがあるページを開き、 2)page2/ にアクセスするとテンプレートを利用してページを表示する、 というサンプルアプリを作りたい場合、コントローラにしてみると、以下のようになる。
package Hello;
use strict;
use Catalyst qw(
-Debug
);
our $VERSION = '0.01';
Hello->config( name => 'Hello', );
Hello->setup;
sub default : Private {
my ($self, $c) = @_;
$c->res->output('Hello World! <a href="page2/">go to page</a>.');
}
sub page2 : Global {
my ($self, $c) = @_;
$c->stash->{message} = 'Page2';
$c->stash->{template} = 'page2.html';
$c->forward('Hello::V::TT');
}
テンプレートファイルは Hello/root 以下に保存するのがおすすめらしい。
Hello/root/page2.html
<center>[% message %]</center>
これで完成。
すごいのは、テスト用の httpd 機能があること。script/hello_server.pl をたたくと、ポート3000番で待機する。
$ script/hello_server.pl
[Sun Jul 10 22:47:47 2005] [catalyst] [debug] Debug messages enabled
[Sun Jul 10 22:47:48 2005] [catalyst] [debug] Loaded dispatcher "Catalyst::Dispatcher"
[Sun Jul 10 22:47:48 2005] [catalyst] [debug] Loaded engine "Catalyst::Engine::HTTP"
[Sun Jul 10 22:47:48 2005] [catalyst] [debug] Found home xxxxxxxxxxxxxxxxxxx
[Sun Jul 10 22:47:48 2005] [catalyst] [debug] Loaded components:
.=----------------------------------------------------------------------------=.
| Hello::V::TT |
'=----------------------------------------------------------------------------='
[Sun Jul 10 22:47:48 2005] [catalyst] [debug] Loaded private actions:
.=-------------------------------------+--------------------------------------=.
| Private | Class |
|=-------------------------------------+--------------------------------------=|
| /default | Hello |
| /page2 | Hello |
'=-------------------------------------+--------------------------------------='
[Sun Jul 10 22:47:48 2005] [catalyst] [debug] Loaded public actions:
.=-------------------------------------+--------------------------------------=.
| Public | Private |
|=-------------------------------------+--------------------------------------=|
| /page2 | /page2 |
'=-------------------------------------+--------------------------------------='
[Sun Jul 10 22:47:48 2005] [catalyst] [info] Application powered by Catalyst 5.30
You can connect to your server at http://localhost:3000/
こんな感じでログを吐きつつ起動。以下、アクセスごとにログが吐かれる。
ブラウザで http://localhost:3000/ にアクセスすると。。。テストできます!。こりゃ便利!
Perl 界で今 HOT な MVC フレームワーク Catalyst のインストール方法
現在もっとも注目されていて評価もかなり高い MVC フレームワークとして Ruby on Rails ってのがあります。Ruby on Rails って方は、「【レポート】Lightweight Language Day and Night - フレームワーク対決 (MYCOM PC)」にスマートにまとめられていますが、
Ruby on Rai...
最近のコネタ
この前の仕事からTipsをダンプ... Catalyst x Lighttod の時、Catalyst は 5.7004 以上必須 Shibuya.pm ...
User/今井貴之/Perl
CPAN: CPAN.jp: チェックプログラム・テ...
暫くぶりにperlで開発していますが、だいぶ進歩していて驚きました。このサイトがとても参考になりました。