最終更新:
catalystmemo 2010年03月08日(月) 15:35:16履歴
Controller(コントローラ)はMVCモデルの構成する3要素の一つであり、
ViewとModelを制御する機構であると一般的に定義される。
そのため、Controllerで行う処理は概ね以下のフローに基づく
1.Clientよりrequest情報を受け取る。
↓
2.request情報に基づきServer-sideのApplication-layerにて、対応するaction(サブルーチン)を選択する。
これをDispatchという。
↓
3.Controllerで定義されたactionを呼び出し、処理を実行する。
↓
(※DB連携等を行う場合には、DBに紐付けされたModel(インスタンス)を
Controller内で参照することで実現する。)
↓
4.response情報を反映させるViewを選択し、表示テンプレートを作成する。
↓
5.response情報をClientへ送信、表示テンプレートにて出力させる。
上記のフローを実現するControllerは、CatalystにおいてはControllerモジュールとして
アプリ雛形にて用意されているヘルパスクリプトを用いた自動生成が可能となっている。
Catalystの役割を果たすControllerモジュールは、アプリ雛形にて用意されている
ヘルパスクリプト'myapp_create.pl'にて自動生成が可能となっている。
'myapp_create.pl'を用いたControllerモジュール生成法は以下の通り。
$ ./myapp/script/myapp_create.pl controller <controller-name>
<controller-name>には、生成したいControllerモジュール名を与える。
上記コマンドを実行することで、Catalyst::Controllerを継承したControllerモジュールが生成される。
Catalystは、各URLに基づき実行すべきactionを選択していく。
action(アクション)は、Controllerで定義されるURLに紐づいたサブルーチンであり、
大きな特徴としてattribute(アトリビュート)と呼ばれる要素が付加されている。
attributeはactionとURLを紐づけるパラメータであり、このパラメータ値を変化させることでactionが選択・実行されるURLの指定が可能となる。
しかしこのattributeの選択を誤ると、想定したURLで実行されるべきactionが正しく選択されない恐れがあるので注意が必要である。
![](https://image02.seesaawiki.jp/c/o/catalystmemo/88b820233988a149.bmp)
そのためCatalystではURLを大きく2要素に分けている。
URLのポート番号までの部分(赤線部)をbase(ベース)、それ以降(青線部)をpath(パス)として扱い、
具体的には各actionに対し、実行させるpathをattributeを用いて指定していく。
またpathにおいてはLocalなpath(ローカルなパス)とGlobalなpath(グローバルなパス)の2種類があり、
Localなpathはnamespace(ネームスペース)を含んだPathである。逆にGlobalなpathは、namespaceを含まないpathである。
namespaceとはアプリ雛形においてactionを定義したControllerモジュールの配置パスを示したものであり、
myapp_create.pl において自動生成したControllerモジュールにおいては、コード内においてpakage句で明示されている。
namespaceの一例
package myapp::Controller::path::app
attributeで定義されているパラメータ値一覧は以下の通り
パタメータ値種類 | actionが実行されるURL |
:Local | base + namespace + action名 |
:Global | base + action名 |
:Path | base + リテラルで指定したpath |
:Private | 内部的なサブルーチンとして実行(URLに紐づかない) |
:LocalRegex | base + namespace + 正規表現で指定したpath |
:Regex | base + 正規表現で指定したpath |
:Args | URLパラメータからの引数制限時に使用 |
:Chained | 複数のactionを連鎖時に使用 |
ex)各attributeを用いたパス指定方法&実行例
- :Local (http://localhost:3000/path/path_test/ でaction 'path_test' 起動)
package test::Controller::path; # 'Controller'以降のnamespaceが反映 sub path_test :Local { # action名もpathに反映 #action flow .... }
- :Global (http://localhost:3000/path_test/ でaction 'path_test' 起動)
package test::Controller::path; # namespaceが無視 sub path_test :Global { # action名のみがpathに反映 #action flow .... }
- :Path (http://localhost:3000/test/path でaction 'path_test' 起動)
package test::Controller::path; # namespaceが無視 sub path_test :Path('/test/path') { # action名も無視、Pathアトリビュートで指定されたリテラルが反映 #action flow .... }
- :LocalRegex (http://localhost:3000/path/test/<文字列> でaction 'path_test' 起動)
package test::Controller::path; # 'Controller'以降のnamespaceが反映 sub path_test :LocalRegex('^/test/(\w*)') { # action名は無視、LocalRegexアトリビュートで指定した正規表現Pathが反映 #caputureアクセサを使えば、文字列をパラメータとして取得可能 print $c->req->capute->[0]; }
- :Regex (http://localhost:3000/path<数字列>/app/ でaction 'path_test' 起動)
package test::Controller::path; # namespaceは無視 sub path_test :LocalRegex('^pass(\d*)/app/') { # action名も無視、LocalRegexアトリビュートで指定した正規表現Pathが反映 #caputureアクセサを使えば、数字列をパラメータとして取得可能 print $c->req->capute->[0]; }
このページへのコメント
VUQHC2 A round of applause for your article. Fantastic.