Catalyst入門: Actionの定義とその処理の流れ(前編)

| コメント(0)

今回は 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

コメントする

About Me

このブログは Masayoshi Sekimura によって書かれています。現在はサンフランシスコ市内に在住し Six Apart, Ltd. でエンジニアをしています。 このブログ以外にオンラインでやっている事は qootas.org/sekimura/ で見ることができます。 メールは sekimura+blog@gmail.com までどうぞ。

このブログ記事について

このページは、sekimuraがApril 27, 2005 12:30 AMに書いたブログ記事です。

ひとつ前のブログ記事は「GLFlickrSaver: OpenGL screensaver with the FlickrAPI」です。

次のブログ記事は「Eternal Sunshine」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

Powered by Movable Type 4.26