今回は Catalyst の Action の定義の仕方や処理の流れについて書いてみます。 Catalyst::Manual::Intro の Action にある説明を簡単にご紹介しますので、version 5 になってかっこよくなった action 定義の仕方を大雑把にでも理解できるかと思います。
Catalyst の Action
Catalyst の Action は以下の例のように 特別な属性(例では ": Private")を持ったサブルーチンで定義されます。
sub default : Private {
my ( $self, $context ) = @_;
$context->response->output('Catalyst rockz!');
}
Catalyst では何種類かの書き方で action(特別な属性を持ったサブルーチン)を 定義できますが、今回は Global と Private について説明していきます。
Global属性で定義されたaction
Global 属性で定義された action はURLへのリクエストによって実行されます。 つまり以下の hello という action を定義すると http://server/hello にアクセスしたときに "Hello!!" と表示するようになります。
package MyApp;
sub hello : Global {
my ( $self, $context ) = @_;
$context->response->output("Hello!!");
}
Private属性で定義されたaction
次に Private 属性で定義された action ですが、こちらはURLへのリクエストによっては実行されません。必ず他のaction内部で定義された "forward" メソッドによって実行されます。 以下を例にとると lib/MyApp.pm で定義した foo という action は http://server/foo ではアクセスできず、default という定義済みのactionによって処理され 'default output' と出力します。
package MyApp;
sub default : Private {
my ( $self, $context ) = @_;
$context->response->output('default output');
}
sub foo : Private {
my ( $self, $context ) = @_;
$context->response->output('foo action !!');
}
forwardメソッドによって実行される様子は 以下のGlobal属性をもつactionと一緒に使ったときの例を参考にしてください。 この例では http://server/hello では 'Hello World!' と表示し http://server/bye では 'Bye Bye!' と表示しますが、Globalなactionではそれぞれ message を定義するだけにし、実際に出力するのは Private な show_message action で処理するようになります。
package MyApp;
sub hello : Global {
my ( $self, $c ) = @_;
$c->stash->{message} = 'Hello World!';
$c->forward('show_message');
}
sub bye : Global {
my ( $self, $c ) = @_;
$c->stash->{message} = 'Bye Bye!';
$c->forward('show_message');
}
sub show_message : Private {
my ( $self, $c ) = @_;
$c->res->output( $c->stash->{message} );
}
あらかじめ登録されたPrivate action
また Private 属性をもつactionにはあらかじめ登録されているものがありますので、その機能と全体の処理流れを把握しておく必要があります。定義済みの Private action は以下のようになります。
- begin : Private
- リクエストURLに該当するactionの呼び出し前に呼び出されます
- auto : Private
- リクエストURLに該当するactionの直前でbeginの後に呼び出されます。
- default : Private
- 他に定義されているactionに当てはまらない場合に呼び出されます。
- end : Private
- リクエストURLに該当するすべてのactionが呼び出しが終わった後に呼び出されます
つまり begin, auto, default, end の流れが基本で 特定のGlobalなactionにマッチするときは default の部分がその action に置き換わると考えてよいでしょう。 以下の例の場合は http://server/a の場合は hoge というGlobalなactionにマッチするので" b a G e" と表示し http://server/、http://server/gaga といったそれ以外URLへのリクエストに対してはdefault の Local action が選択され " b a D e" と表示されます。
sub begin : Private {
my ( $self, $c ) = @_;
$c->stash->{'msg'} = ' b';
}
sub auto : Private {
my ( $self, $c ) = @_;
$c->stash->{'msg'} .= ' a';
}
sub default : Private {
my ( $self, $c ) = @_;
$c->stash->{'msg'} .= ' D';
}
sub hoge : Global {
my ( $self, $c ) = @_;
$c->stash->{'msg'} .= ' G';
}
sub end : Private {
my ( $self, $c ) = @_;
$c->stash->{'msg'} .= ' e';
$c->res->output($c->stash->{'msg'});
}
次回
次回は MyApp::C::Page といった Controller を定義してひとつのアプリケーションの中で論理ドメインをわける方法を紹介したいと思います。
おまけ
この奇怪なactionに属性をもたせているのは attributes という perl のコアに取り込まれているモジュールによるものだそうですが、私は初めて見ました。。perldoc attributes しなきゃ。 あと perlsub にも少し情報がありますね。あと、Catalyst::Engine の handler からの内部処理の流れをメモしたものを http://qootas.org/kwiki/index.cgi?CatalystInternal さらしておきます。フレームワークそのものに興味のある方はこちらもあわせてご覧ください。

Comments