- Timestamp:
- 06/06/08 05:25:48 (5 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
docs/perldoc/Catalyst/Manual/ExtendingCatalyst.pod
- Property svn:eol-style set to native
r13183 r13315 1 =head1 名前 (NAME)2 3 Catalyst::Manual::ExtendingCatalyst - フレームワークを拡張する4 5 =head1 概要 (DESCRIPTION)1 =head1 名前 2 3 Catalyst::Manual::ExtendingCatalyst - Catalystを拡張する (version 5.013) 4 5 =head1 概要 6 6 7 7 This document will provide you with access points, techniques and best … … 9 9 ways to abstract and use your own code. 10 10 11 このドキュメントでは Catalyst を拡張する方法やどうやってエレガントにあなたのコー 12 ドを抽象化するかについて論じます。 11 このドキュメントではCatalystフレームワークをどこから拡張するか、どうやって拡張するか、そしてどう拡張するのがベストなのかを紹介します。Catalystフレームワークを抽象化して自分なりのコードで差し替える方法にもいろいろありますが、なるべくエレガントなやり方を覚えていってください。 13 12 14 13 The design of Catalyst is such that the framework itself should not … … 18 17 and their consequences. 19 18 20 Catalyst はいろんな方法で拡張できるので、あなたは混乱しているかもしれません。この 21 ドキュメントではそのあたりの詳細を論じます。 19 Catalystは「フレームワークそのものの制約でできない」ことがないように設計されています。いろいろなところでふるまいを変えたり拡張したりできるようになっている分、混乱しやすいともいえますが、このドキュメントを読めば、どのようなことができるか、いまどうしているか、そしてその結果どうなるかが理解できるはず。 22 20 23 21 Please read the L<BEST PRACTICES> section before deciding on a design, … … 26 24 most if we all work together and coordinate. 27 25 28 あなたのコードを CPAN にうpするまえに、とりあえず L<BEST PRACTICES> の章をよみま 29 しょう。 Catalyst の開発者とユーザコミュニティはあなたとともにあります。 26 アプリやモジュールを設計する前に、ぜひL<BEST PRACTICES>の項を読んでください。CPANにアップしようと思っているならなおさらです。Catalystの開発陣にとってもユーザコミュニティ(B<みなさんもその一員ですからね!>)にとっても、全員の足並みが揃っているにこしたことはないのですから。 30 27 31 28 If you are unsure on an implementation or have an idea you would like … … 38 35 starting. 39 36 40 あなたがなにか実装にまつわるアイディアをもっているのであれば、Catalyst の ML, 41 IRC などで話しかけてください。 42 43 =head1 ベストプラクティス(BEST PRACTICES) 37 実装に悩んだり、規約(RFC)にしたいアイディアがあるなら、ぜひ質問や提案をメーリングリスト(See L<Catalyst/SUPPORT>)に流してください。C<irc.perl.org>のC<#catalyst>チャンネルに来るのもおすすめです。これから実装しようと思っているモジュールがすでに存在しないか確認したいときもそうですね。ぴったりのモジュールを教えてもらえるかもしれませんし、とっかかりくらいは得られると思いますよ。 38 39 =head1 BEST PRACTICES 44 40 45 41 During Catalyst's early days, it was common to write plugins to … … 49 45 the scope of its influence as close as possible to where it belongs. 50 46 51 Catalyst が若かりしころ、複数アプリにまたがる機能はプラグインにするのがよいとされ 52 えいましたが、現在ではもっとフレキシブルでパワフルな方法があります。 47 Catalystも当初はプラグインを書いてアプリケーションのどこからでも機能を利用できるようにするのが一般的でしたが、その後、Catalystもずいぶん柔軟・強力になったので、すぐに抽象化の仕方やインタフェースを変えて、なるべくスコープの及ぶ範囲を狭くするのがベストプラクティスになりました。 53 48 54 49 For those in a hurry, here's a quick checklist of some fundamental … … 56 51 forward to L</Namespaces>. 57 52 58 もし君がめっちゃいそいでいるのなら、以下に必須のポイントに関するクイックチェック 59 リストを容易したからそれだけでもよんでいきたまえ。もし君がまったりとこの文書を全 60 部読むつもりなら L</Namespaces> に進む。 61 62 =head2 3分間チェックリスト(Quick Checklist) 53 せっかちな方は大事なポイントをまとめた早見表をどうぞ。ひととおり目を通しておこうという方は、L</Namespaces>の話からでもOKです。 54 55 =head2 Quick Checklist 63 56 64 57 =over 65 58 66 =item C<CatalystX::*> というネームスペースをつかいましょう(Use the C<CatalystX::*> namespace if you can!) 59 =item Use the C<CatalystX::*> namespace if you can! 60 61 なるべくC<CatalystX::*>というネームスペースをつかいましょう! 67 62 68 63 If your extension isn't a Model, View, Controller, Plugin, or Engine, … … 70 65 <CatalystX::> instead. 71 66 72 もしあなたの拡張が Model でも View でも Controller でも Plugin でも Engine でもな 73 ければ、それは C<Catalyst::> というネームスペースにおくべきではありません。 74 C<CatalystX::> をかわりにつかってください。 75 76 =item プラグインはつくらない(どうしてもつくらなきゃいけない場合をのぞいて)!(Don't make it a plugin unless you have to!) 67 もしあなたの拡張が Model でも View でも Controller でも Plugin でも Engine でもないなら、C<Catalyst::> というネームスペースにおくべきではありません。C<CatalystX::> をかわりにつかってください。 68 69 =item Don't make it a plugin unless you have to! 70 71 どうしようもないとき以外はプラグインにしないこと! 77 72 78 73 A plugin should be careful since it's overriding Catalyst internals. … … 80 75 base Controller or Model. 81 76 82 プラギンは Catalyst の内部をうわがきしちゃうので、注意してね!もしチミのプラグイン 83 が、内部を上書きしたいんでなければ、Controller か Model にしてね! 84 85 =item コミュニティがあるから利用しちゃおう!(There's a community. Use it!) 77 プラグインは Catalyst の内部を上書きしてしまうので、(書くときも使うときも)細心の注意が必要。どうしてもCatalystの内部をいじる必要があるのでなければ、ベースControllerにするか、Modelにすること。 78 79 =item There's a community. Use it! 80 81 コミュニティがあるんだから活用すること! 86 82 87 83 There are many experienced developers in the Catalyst community, 88 84 there's always the IRC channel and the mailing list to discuss things. 89 85 90 Catalyst には IRC も ML もあるから、どんどん利用しちゃおう! 91 92 =item テストとドキュメンテーションはしっかりね!(Add tests and documentation!) 86 Catalystコミュニティにはベテランプログラマがたくさんいますし、話をしたければいつでもIRCチャンネルなりメーリングリストなりがある、ということ。 87 88 =item Add tests and documentation! 89 90 テストやドキュメントも忘れずに! 93 91 94 92 This gives a stable basis for contribution, and even more importantly, … … 96 94 L<Catalyst::Manual::Tutorial::Testing> for more information. 97 95 98 あたりまえのことだけど、テストとドキュメンテーションをしない人はお尻ペンペンだよ! 96 こういうのがあるとアプリやモジュールが安定しますし、なにより信頼感がうまれます。いちばん簡単なのはテストアプリを用意すること。詳しくはL<Catalyst::Manual::Tutorial::Testing>を読みましょう。 99 97 100 98 =back 101 99 102 =head2 ネームスペース(Namespaces)100 =head2 Namespaces 103 101 104 102 While some core extensions (engines, plugins, etc.) have to be placed … … 106 104 developers to use the C<CatalystX::*> namespace if possible. 107 105 108 コアの拡張(engine や plugin とか)は、C<Catalyst::*> におくべきだけど、そういうの 109 つくるときは開発者に相談してからにしよう。できることなら C<CatalystX::*> におこう。 110 111 (訳注: CPAN にアップロードする場合、相談してからやらないと mst に痛烈に DIS られます) 106 エンジンやプラグインのようにコアを拡張する場合はC<Catalyst::*>のネームスペース内に入れてもらうしかありませんが、Catalystのコアメンバーは、一般の開発者のみなさんにはなるべくC<CatalystX::*>のネームスペースを使ってほしいと思っています。 112 107 113 108 When you try to put a base class for a C<Model>, C<View> or … … 119 114 as examples. 120 115 121 もしC<Model>, C<View>, C<Controller>のベースクラスをC<MyApp>の下、たとえばC<MyApp::Controller::Foo>、に置くとCatalystがそれをロードしようとするのでちょっとトラぶっちゃうと思います。解決方法は簡単で、C<MyApp::Base::Controller::*>::やC<MyApp::ControllerBase::*>なんかのネームスペースを使うといいでしょう。 122 123 =head2 それをシンプルなモジュールにすることはできませんか?(Can it be a simple module?) 116 C<MyApp::Controller::Foo>のように、C<MyApp>ディレクトリの直下にC<Model>やC<View>、C<Controller>のベースクラスを置いてしまうと、ベースクラスもアプリケーションのコンポーネントとみなされて問題が起こる可能性があるので、別のネームスペースを使いましょう。C<MyApp::Base::Controller::*>とかC<MyApp::ControllerBase::*>というのがよくある例です。 117 118 =head2 Can it be a simple module? 119 120 ふつうのモジュールにした方がよくないですか? 124 121 125 122 Sometimes you want to use functionality in your application that … … 131 128 try to load them as components. 132 129 133 Catalyst はたんなる Perl であることを思いだしてください。C<use> でいつでもモジュー 134 ルをつかえるんですよ。フレームワークと連携することが必要ないアプリケーション専用 135 のコードであれば、C<MyApp::*> というネームスペースをつかってください。C<Model>, 136 C<Controller>, C<View> というネームスペースにはおかないでください。このネームスペー 137 スにおくと Catalyst がコンポーネントとしてロードしちゃいまっせ。 130 つくっているアプリによっては、Catalystとはまったく関係ない機能を使いたくなることもあるものですが、Catalystは単なるPerlのコードでしかないということはお忘れなく。必要ならいつでもモジュールをC<use>すればいいんです。特定のアプリ専用のコードの場合、Catalystの機能が必要ないならC<MyApp::*>ネームスペースのなかに入れてしまってもかまいません。ただし、C<Model>やC<Controller>、C<View>の下には入れないこと。コンポーネントとしてロードされてしまいますから。 138 131 139 132 Writing a generic component that only works with Catalyst is wasteful … … 147 140 convenient. 148 141 149 Catalyst に依存した一般的なコンポーネントをつくることは、あなたの時間を無駄に浪費 150 させます。素の Perl モジュールを書くことを検討してください。そして、Catalyst とは 151 ほんのちょっとの連携コードで連携させてください。このような方法論でつくられたモ 152 ジュールの代表例は Catalyst::Model::DBIC::Schema ですので参考にしてください。この 153 方法のよさは、DBIC のスキーマが完全に Catalyst の外でうごいているということです。 154 こうすることによって、テストが楽になり、コマンドラインスクリプトも簡単に書けます。 155 現実の Catalyst の Model は、ほんとにちょっとの連携コードで便利につかえるようにつ 156 なぎこまれてるのだ。 142 一般的なコンポーネントなのにCatalystでしか使えないようなものを書くのは時間のむだです。そういうのはプレーンなperlモジュールにしてしまいましょう。そのあとでちょっとした「つなぎ」を書いてCatalystで使えるようにすればいいんです。L<Catalyst::Model::DBIC::Schema|Catalyst::Model::DBIC::Schema>がそういうアプローチをとっています。そうしておくと、「Catalyst用の」DBICスキーマがCatalystの外でも何の問題もなく使えますから、テスト(やコマンドラインツール)を書くのが簡単になるのが長所。Catalyst用のModel本体はスキーマを使いやすくするためのつなぎを数行書くだけです。 157 143 158 144 If you want the thinnest interface possible, take a look at 159 145 L<Catalyst::Model::Adaptor|Catalyst::Model::Adaptor>. 160 146 161 もし、薄いインターフェースで連携できるんなら Catalyst::Model::Adaptor でつなぎこ 162 むのがよいです。 163 164 =head2 継承とメソッドのうわがき。(Inheritance and overriding methods) 147 もっとインタフェースを薄くしたいのであれば、L<Catalyst::Model::Adaptor|Catalyst::Model::Adaptor>をどうぞ。 148 149 =head2 Inheritance and overriding methods 150 151 継承とメソッドのオーバーライド 165 152 166 153 While Catalyst itself is still based on L<NEXT> (for multiple 167 inheritance), extension developers are encouraged to use L<Class::C3>, 168 which is what Catalyst will be switching to in some point in the 169 future. 170 171 CatalystはまだNEXTベースだけど拡張モジュールを作る人はClass::C3を使うといいよ。Catalystもそのうちそうなるから。 154 inheritance), extension developers are encouraged to use L<Class::C3>,which is what Catalyst will be switching to in some point in the future. 155 156 Catalyst自体はまだ(多重継承できるように)L<NEXT>をベースにしていますが、拡張を開発する人はL<Class::C3>を使ってください。将来的にはCatalyst本体もこちらに切り替わる予定です。 172 157 173 158 When overriding a method, keep in mind that some day additionally … … 177 162 you can pass your complete arguments to the original method via C<@_>: 178 163 179 メソッドをオーバーライドする場合は 将来引数が追加されることを考慮して以下のようにするといい。164 メソッドをオーバーライドする場合は、そのメソッドにいつか新しい引数が追加されるかもしれないということを忘れずに。特に最後のパラメータがフラットなリストでない場合は要注意。メソッドをオーバーライドするときは呼び出し元をC<@_>からshiftで取り出してから、残りを割り当てるようにしましょう。こうしておけば、もとのメソッドにすべての引数を渡すときにC<@_>を使えるようになります。 180 165 181 166 use Class::C3; ... … … 187 172 If you would do the common 188 173 174 よくあることですが、こんな風にしてしまうと 175 189 176 my ($self, $foo, $bar) = @_; 190 177 … … 192 179 will be passed along and the method is future proof: 193 180 181 かなりきたない方法を使わないと、すべての引数を次のメソッドに回して将来の変更に備えることができなくなってしまいます。 182 194 183 $self->next::method(@_[ 1 .. $#_ ]); 195 184 196 =head2 テストとドキュメンテーション(Tests and documentation) 185 =head2 Tests and documentation 186 187 テストとドキュメント 197 188 198 189 When you release your module to the CPAN, proper documentation and at … … 203 194 invaluable. 204 195 205 CPAN にモジュールをリリースするにあたっては、きちんとしたドキュメンテーションと、 206 テストスィーツ(use_ok してりゃいいってもんじゃないよ)を提供してくださいな。 196 CPANにモジュールをアップするなら、きちんとドキュメントを書いて、最低でも基本的なテストは用意しましょう(悪いけど、PODのテストや、ただC<use_ok>するだけのものではだめですよ)。こうしておくとほかの人がパッチなどを送りやすくなりますし、作者であるあなたがユーザのことを気にかけているという証拠にもなります。ほかの人にも自分のモジュールを使ってほしいなら、こういうのはとっても大事です。 207 197 208 198 If you're just getting started, try using … … 210 200 tests for your module. 211 201 212 もし君が、あたらしくつくりはじめるんなら CatalystX::Starter をつかってみてくださ 213 いな。テストの例がはいっているよ。 214 215 =head2 メンテナンス(Maintenance) 202 これから書き始めるのであれば、L<CatalystX::Starter|CatalystX::Starter>を使うとテストのサンプルが生成されます。 203 204 =head2 Maintenance 205 206 メンテナンス 216 207 217 208 In planning to release a module to the community (Catalyst or CPAN and … … 219 210 date, including fixing bugs and accepting contributions. 220 211 212 モジュールを(Catalyst、あるいはCPANやPerlの)コミュニティに公開するつもりがあるなら、きちんと更新できるか、バグをなおしたりパッチをあてたりできるだけのリソースがあるか、よく考えること。 213 221 214 If you're not sure about this, you can always ask in the proper 222 215 Catalyst or Perl channels if someone else might be interested in the 223 216 project, and would jump in as co-maintainer. 217 218 自信がないなら、いつでもCatalystやPerl向けの適切なチャンネルでたずねてみましょう。誰かが興味を持ってくれて、共同メンテナーになってくれるかもしれません。 224 219 225 220 A public repository can further ease interaction with the … … 228 223 are broadly preferred in the Catalyst community. 229 224 225 公開リポジトリがあるとさらにコミュニティとのやりとりが簡単になります。たとえリードオンリーであろうと、ほかの人に現在の開発版にパッチを書いてもらえるようになるのですから。Catalystコミュニティではsubversion(SVN、SVK)が広く使われています。 226 230 227 If you're developing a Catalyst extension, please consider asking the 231 228 core team for space in Catalyst's own subversion repository. You can … … 233 230 list. 234 231 235 リリースしたモジュールをアップデートしたり、バグフィックスしたりしてね。 236 237 みんながパッチを送れるように開発中のリポジトリを公開しておくのもいいね。 238 239 とか。 240 241 =head2 コンテキストオブジェクト(The context object) 232 Catalystの拡張を書いているなら、ぜひIRCやCatalystの開発者向けメーリングリストでコアメンバーに声をかけて、本家のsubversionリポジトリに入れてもらうことを考えてみてください。 233 234 =head2 The context object 235 236 コンテキストオブジェクトについて 242 237 243 238 Sometimes you want to get a hold of the context object in a component … … 246 241 context information (current language, for example). 247 242 248 起動時に作成されたコンポーネントの中でコンテキストオブジェクトを使いたい場合もあります。243 場合によっては(まだコンテキストが存在していない)起動時に作成したコンポーネントにコンテキストオブジェクトを持たせたい場合もあります。stashなどからなにか(たとえば現在の言語など)を読み込みたいモデルの場合は特にそうです。 249 244 250 245 If you use the context object in your component you have tied it to an … … 253 248 outside of Catalyst, for example in cronjobs. 254 249 255 しかし、コンポーネントの中でコンテキストオブジェクトを使うということはリクエストとコンポーネントを結びつけるという意味であり、Catalystの外でそのコンポーネントを使おうとした場合に問題となります。250 ただし、コンポーネントのなかでコンテキストオブジェクトを使うと、そのコンポーネントは既存のリクエストにしばられてしまうことになります。つまり、そのコンポーネント(たいていの場合はモデル)をCatalystの外、たとえばcronjobのなかで使おうとしたときに困ることになりかねません。 256 251 257 252 A stable solution to this problem is to design the Catalyst model … … 266 261 directly. 267 262 268 解決方法はCatalystのモデルはモデルロジックとは切り離して設計することです。たとえばL<Catalyst::Model::DBIC::Schema>を見るといいでしょう。スキーマはCatalystとは切り離されてます。このような設計はカプセル化を促進し、メンテナンス性もよくなります。263 確実な解決策としては、Catalystのモデルを、ベースとなるモデルのロジック層から分離してしまうという手があります。たとえばL<Catalyst::Model::DBIC::Schema>の場合、スキーマはCatalystの外に用意できます。Webのことなどいっさい知りません。このように設計しておくと、確実にカプセル化できますし、開発にしろメンテにしろ、はるかに簡単になります。で、このスキーマをアプリとつなぐときにL<Catalyst::Model::DBIC::Schema>を使うわけです。そうすると、C<MyApp::DBIC>(もちろんこの名前はサンプルですよ)というモデルのほかに、C<MyApp::DBIC::TableName>というモデルが用意されて、直接リザルトソースにアクセスできるようになります。 269 264 270 265 By creating such a thin layer between the actual model and the … … 273 268 information from the context object. 274 269 275 このように 薄いレイヤーを実際のモデルとCatalystの間に用意することで、モデル自身はアプリケーションに結び付けず、レイヤーの部分はコンテキストオブジェクトからの情報を使ってモデルAPIにアクセスできるようになります。270 このように実際のモデルとCatalystアプリとの間に薄いレイヤーをつくっておくと、スキーマそのものがアプリにしばられることはなくなりますし、間に入っているレイヤーのおかげでコンテキストオブジェクトの情報を利用してモデルのAPIにアクセスできるようになります。 276 271 277 272 A Catalyst component accesses the context object at request time with 278 273 L<Catalyst::Component/"ACCEPT_CONTEXT($c, @args)">. 279 274 280 CatalystのコンポーネントはL<Catalyst::Component/"ACCEPT_CONTEXT($c, @args)">を使うことでリクエスト時にコンテキストオブジェクトにアクセスできます。 281 282 =head1 設定(CONFIGURATION) 275 ちなみにCatalystのコンポーネントはリクエスト時でもL<Catalyst::Component/"ACCEPT_CONTEXT($c, @args)">を使えばコンテキストオブジェクトにアクセスできます。 276 277 =head1 CONFIGURATION 278 279 設定について 283 280 284 281 The application has to interact with the extension with some 285 282 configuration. There is of course again more than one way to do it. 286 283 287 アプリケーションはいくつかの設定によって拡張モジュールと協調します。もちろん、やり方は複数あります。 288 289 =head2 アトリビュート(Attributes) 284 アプリが拡張とやりとりする場合はなんらかの設定が必要ですが、もちろんこれにもやり方はいろいろあります。 285 286 =head2 Attributes 287 288 アトリビュート 290 289 291 290 You can specify any valid Perl attribute on Catalyst actions you like. … … 295 294 action: 296 295 297 Perlで使える属性がすべて使えます。属性はC<Catalyst::Action>のインスタンスでC<attributes>アクセサを介して使用できます。296 Catalystのアクションには文法的に正しければどんなアトリビュートでもつけられます(有効なアトリビュートについてはL<attributes/"Syntax of Attribute Lists">をどうぞ)。これらはC<Catalyst::Action>のC<attributes>アクセサ経由で取得できます。一例をあげましょう。 298 297 299 298 sub foo : Local Bar('Baz') { … … 311 310 class|/"Component Base Classes">. 312 311 313 これはレスポンスボディにBazをセットします。値は常に配列のリファレンスです。 314 315 =head2 カスタムアクセサをつくる(Creating custom accessors) 312 こうすると、レスポンスのbodyがC<Baz>になります。アトリビュートの値はかならず配列のリファレンスになります。わかると思いますが、アトリビュートを使ってアクションの設定をすることもできます。このアトリビュートはL<コンポーネントの設定|/"Component Configuration">でも指定・変更できますし、自前のL<コンポーネントのベースクラス|/"Component Base Classes">を用意すればCatalystがアトリビュートを見つけたときにすぐ処理をするようにもできます。 313 314 =head2 Creating custom accessors 315 316 カスタムアクセサをつくる 316 317 317 318 L<Catalyst::Component> uses L<Class::Accessor::Fast> for accessor … … 319 320 information. 320 321 321 L<Catalyst::Component> はアクセサをつくるのに L<Class::Accessor::Fast> をつかって 322 います。 323 324 =head2 コンポーネントの設定(Component configuration) 322 L<Catalyst::Component>はL<Class::Accessor::Fast>を使ってアクセサをつくっています。使い方についてはそれぞれのドキュメントを参照ということで。 323 324 =head2 Component configuration 325 326 コンポーネントの設定 325 327 326 328 At creation time, the class configuration of your component (the one … … 330 332 object's hash reference. So, if you read possible configurations like: 331 333 332 作成時にコンポーネントのクラス設定(C<$self-E<gt>config>で使えるやつ)はアプリケーション設定で使用可能な設定とマージされます。で、これらはコントローラオブジェクトのハッシュリファレンスに保存されます。なので設定は以下のように読み込むことができます。 334 コンポーネントのインスタンスを作成するときには、クラスの設定(C<$self-E<gt>config>でアクセスできるもの)とアプリケーションの設定(直書きしてあったり設定ファイルから読み込んだりしたもの)をマージしたものがオブジェクトのハッシュリファレンスに保存されます。だから、このようにすれば 333 335 334 336 my $model_name = $controller->{model_name}; … … 338 340 component configuration. 339 341 340 C<config>アクセサは常に元のクラス設定のみを含んでいて、コンポーネント設定のためには使われません。342 正しい値が得られます。C<config>にはかならずもとのクラスの設定のみが入っているようにしてください。コンポーネントの設定としては使ってはいけません。 341 343 342 344 You are advised to create accessors on your component class for your … … 346 348 L<Class::Accessor::Fast>: 347 349 348 設定値用に以下のようなアクセサを用意しておくと便利です。350 コンポーネントクラスには設定用のアクセサを用意しましょう。これはグッドプラクティスですし、設定のキーに間違いがあったときにエラーを見つけやすくなります。L<Catalyst::Component>にはL<Class::Accessor::Fast>のC<mk_ro_accessors>メソッドが生えていますので、それを使えばよいでしょう。 349 351 350 352 use base 'Catalyst::Controller'; … … 353 355 my $model_name = $controller->model_name; 354 356 355 =head1 実装(IMPLEMENTATION) 357 =head1 IMPLEMENTATION 358 359 実装について 356 360 357 361 This part contains the technical details of various implementation … … 359 363 implementation, if you haven't already. 360 364 361 いろんな実装方法の詳細を説明します。 362 363 =head2 Actionクラス(Action classes) 365 ここではいろいろな拡張の実装方法についての技術的な話をします。まだ読んでいない方は実装を始める前にL</"BEST PRACTICES">を読んでください。 366 367 =head2 Action classes 368 369 アクションクラス 364 370 365 371 Usually, your action objects are of the class L<Catalyst::Action>. … … 369 375 created Catalyst application in your root controller: 370 376 371 アクションオブジェクトはL<Catalyst::Action>クラスのインスタンスです。C<ActionClass>属性を使うことでこの挙動に影響を与えることができます。広く使われている例ではL<Catalyst::Action::RenderView>があります。377 ふつうアクションオブジェクトはL<Catalyst::Action>クラスのものですが、C<ActionClass>アトリビュートを使うとアクションの実行やディスパッチ処理をオーバーライドできます。 372 378 373 379 sub end : ActionClass('RenderView') { } … … 378 384 subclass: 379 385 380 大抵の場合、C<execute>やC<match>メソッドをオーバーライドすることになるでしょう。サブクラスでexecuteメソッドをオーバーライドすることでメソッドをラップすることができます。386 ふつうオーバーライドしたくなるのはC<execute>メソッドやC<match>メソッドでしょう。executeはもちろんメソッドのコードを実行するためのものです。このメソッドをサブクラスのなかでオーバーライドすると、前後に処理を追加できます。 381 387 382 388 package Catalyst::Action::MyFoo; use strict; … … 397 403 in the L<Catalyst::Action> class. 398 404 399 L<Catalyst::Action>クラスにある元のC<execute>メソッドに再度ディスパッチするためにL<Class::C3>を使ってます。405 ここではL<Class::C3>を使って、L<Catalyst::Action>のなかにあるもとのC<execute>メソッドにディスパッチしなおしています。 400 406 401 407 The Catalyst dispatcher handles an incoming request and, depending … … 406 412 the action will match and add new matching criteria. 407 413 408 C <match>メソッドをオーバーライドするとCatalystのディスパッチャの挙動を変更できます。414 Catalystのディスパッチャは受け取ったリクエストを解釈し、タイプに応じて適切なターゲットやチェーンを呼び出すわけですが、場合によってはアクションそのものに(あるいはコントローラ経由で)現在のリクエストにマッチしているか確認することもあります。このときに使われるのがC<match>メソッドです。だから、これをオーバーライドすると、どのアクションがマッチするかを変更できますし、新しいマッチングルールを追加することもできます。 409 415 410 416 For example, the action class below will make the action only match on 411 417 Mondays: 412 418 413 たとえば 以下のアクションクラスは月曜日にだけマッチします。419 たとえば、このアクションクラスは月曜日に限ってマッチします。 414 420 415 421 package Catalyst::Action::OnlyMondays; use strict; … … 427 433 And this is how we'd use it: 428 434 429 こうやって使います。435 使い方はこんな感じ。 430 436 431 437 sub foo: Local ActionClass('OnlyMondays') { … … 438 444 a component base class providing an attribute handler. 439 445 446 こういうアクションクラスをしょっちゅう使うとか、既存のベースクラスをもっと便利に使いたい場合は、コンポーネントのベースクラスにアトリビュートハンドラを持たせることもできます。 447 440 448 For further information on action classes, please refer to 441 449 L<Catalyst::Action> and L<Catalyst::Manual::Actions>. 442 450 443 =head2 コンポーネントなクラス(Component base classes) 451 アクションクラスの詳細についてはL<Catalyst::Action>やL<Catalyst::Manual::Actions>をどうぞ。 452 453 =head2 Component base classes 454 455 コンポーネントのベースクラス 444 456 445 457 Many L<Catalyst::Plugin> that were written in Catalyst's early days … … 448 460 not polluting the global namespace in the context object. 449 461 450 Catalyst がうまれたての頃に多くの L<Catalyst::Plugin> が書かれました。462 Catalystの初期に書かれたL<Catalyst::Plugin>の多くは、本当は単なるコントローラのベースクラスにするべきものでした。そうしておけば機能をひとつのコントローラのなかに閉じこめておけますし、コンテキストオブジェクトのグローバルなネームスペースを汚すこともなかったのです。 451 463 452 464 You can provide regular Perl methods in a base class as well as 453 465 actions which will be inherited to the subclass. Please refer to 454 466 L</Controllers> for an example of this. 467 468 ベースクラスにはふつうのメソッドを書くこともできますし、アクションを書くこともできます(これらはサブクラスに継承されます)。サンプルについてはL</Controllers>をどうぞ。 455 469 456 470 You can introduce your own attributes by specifying a handler method … … 460 474 already provided via the C<+> prefix for action classes. A simple 461 475 462 シンプルな 476 コントローラのベースクラスにハンドラメソッドを用意すると、自前のアトリビュートを使えるようにもできます。たとえば、C<FullClass>というアトリビュートを使ってアクションクラス名の完全修飾名を指定したい場合は、こんな風に書けます(ただし、この機能はすでに本体に実装されています。使い方はアクションクラスにC<+>というプレフィックスをつけるだけ。つまり、こう書くだけで 463 477 464 478 sub foo : Local ActionClass('+MyApp::Action::Bar') { ... } … … 466 480 will use C<MyApp::Action::Bar> as action class. 467 481 468 は、C<MyApp::Action::Bar> を Action クラスとしてつかいます。482 C<MyApp::Action::Bar>がアクションクラスになります)。 469 483 470 484 package MyApp::Base::Controller::FullClass; use strict; use base … … 481 495 Catalyst attribute: 482 496 497 念のため、引数を省略しなかったのは単に抜けをつくりたくなかったからです。サブクラスではこのアトリビュートをほかのアトリビュートと同様に利用できます。 498 483 499 package MyApp::Controller::Foo; 484 500 use strict; … … 489 505 1; 490 506 491 =head2 コントローラ(Controllers) 507 =head2 Controllers 508 509 コントローラ 492 510 493 511 Many things can happen in controllers, and it often improves … … 495 513 classes. 496 514 515 コントローラではさまざまな処理が行われるので、コードの一部を抽象化して再利用できるベースクラスにしてしまった方がメンテナンス性が向上する場合が多いです。 516 497 517 You can provide usual Perl methods that will be available via your 498 518 controller object, or you can even define Catalyst actions which will 499 519 be inherited by the subclasses. Consider this controller base class: 520 521 ふつうのメソッドを用意しておけばコントローラオブジェクトから利用できますし、アクションを定義してサブクラスに継承させることさえできます。たとえばこんなコントローラのベースクラスを考えてみましょう。 500 522 501 523 package MyApp::Base::Controller::ModelBase; … … 528 550 handling, input validation, and probably other things. 529 551 552 この例ではシンプルなアクションをふたつ実装しています。C<list>アクションは(いまのところ存在していない)C<base>アクションにぶら下がり、設定済みのC<model_name>や検索条件、検索オプションを取り出してリザルトセットをstashに入れる役割をしています。このアクションはL<チェーン|Catalyst::DispatchType::Chained>の終端です。もう一方のC< load >アクションはチェーンの中間部分で、引数をひとつとり、その値をIDとみなして、設定済みのモデルから該当する行を読み込みます。念のため、上のコードは説明のためにあえて簡単にしていますが、ほんとうはエラー処理や入力値の検証などが必要ですよ。 553 530 554 The class above is not very useful on its own, but we can combine it 531 555 with some custom actions by sub-classing it: 556 557 上のクラスそのものはあまり役に立ちませんが、サブクラス化すればほかのカスタムアクションも組み込めます。 532 558 533 559 package MyApp::Controller::Foo; … … 553 579 class. Next comes the C<base> action, where everything chains off of. 554 580 581 このクラスはさっきつくったコントローラがベースクラスになっています。最初に親クラスで使っていた設定があって、次にすべてのチェーンの起点となるC<base>アクションが来ています。 582 555 583 Note that inherited actions act like they were declared in your 556 584 controller itself. You can therefor call them just by their name in … … 558 586 important part of what makes this technique so useful. 559 587 588 継承したアクションもコントローラのなかで宣言されているかのようにふるまいます。C<forward>やC<detach>、C<Chained(..)>の指定にアクション名を書くだけで呼び出せるというのが、この便利なテクニックの肝です。 589 560 590 The new C<view> action ties itself to the C<load> action specified in 561 591 the base class and outputs the loaded row's C<name> and C<description> … … 563 593 publicly available paths: 564 594 595 新しいC<view>というアクションは、ベースクラスで指定されているC<load>アクションにぶら下がって、読み込まれた行のC<name>とC<description>を出力します。この段階でC<MyApp::Controller::Foo>というコントローラには以下のようなパスがパブリックになっています。 596 565 597 =over 566 598 … … 569 601 Will call the controller's C<base>, then the base classes C<list> 570 602 action. 603 604 コントローラのC<base>アクション、ベースクラスのC<list>アクションの順に呼ばれます。 571 605 572 606 =item /foo/$id/view … … 576 610 display some fields out of the object. 577 611 612 まずはコントローラのC<base>が呼ばれ、次にC<load>でC<$id>に対応する行が読み込まれ、それからC<view>で行オブジェクトのフィールドが出力されます。 613 578 614 =back 579 615 580 =head2 モデルとビュー(Models and Views) 616 =head2 Models and Views 617 618 モデルとビュー 581 619 582 620 If the functionality you'd like to add is really a data-set that you … … 584 622 files, it might be better suited as a model. 585 623 624 追加したい機能が実は内部文書の種類や画像、ファイルといったデータセットの操作だった場合は、モデルにした方がよいかもしれません。 625 586 626 The same applies for views. If your code handles representation or 587 627 deals with the applications interface and should be universally 588 628 available, it could be a perfect candidate for a view. 629 630 ビューの場合もそう。追加したいコードが表示まわりだったり、アプリケーションのインタフェースにかかわるものだったり、アプリケーションの外からも利用できないといけない場合は、ビューにするのが一番かもしれません。 589 631 590 632 Please implement a C<process> method in your views. This method will … … 593 635 but a simple Perl method. 594 636 637 ビューの場合はC<process>メソッドを実装してください。このメソッドはアクションを指定せずにコンポーネントにC<forward>したときに呼ばれるものです。C<process>はB<Catalystのアクションではなく>、単なるPerlのメソッドですのでお間違えなく。 638 595 639 You are also encouraged to implement a C<render> method corresponding 596 640 with the one in L<Catalyst::View::TT>. This has proven invaluable, … … 598 642 generation. 599 643 644 また、L<Catalyst::View::TT>のようなC<render>メソッドも実装しましょう。このメソッドがあると、もっと細かいコンテンツ生成をしたいときにもビューを使えるようになるのでとても便利です。 645 600 646 Here is some example code for a fictional view: 647 648 これは架空のビューのコード例です。 601 649 602 650 package CatalystX::View::MyView; … … 618 666 1; 619 667 620 =head2 プラグイン(Plugins) 668 =head2 Plugins 669 670 プラグイン 621 671 622 672 The first thing to say about plugins is that if you're not sure if … … 626 676 became obvious that this qualifies as bad practice. 627 677 628 まずもって、あなたがプラグインをつくろうとおもっている場合、十中八九プラグインを 629 つくるべきではありません。 678 まず、プラグインにする必要があるかどうかわからないモジュールは、たぶんプラグインにするべきではありません。昔はCatalystに機能を追加したくなったらプラグインを書いて、その機能を呼び出すアクセサを用意するのが一般的でしたが、Catalystがいろいろな人に使われるようになってくると、これはバッドプラクティスであることがわかりました。 630 679 631 680 By designing your module as a Catalyst plugin, every method you … … 634 683 should be only doing that when you really need to. 635 684 636 あなたのモジュールを Catalyst のプラグインとして実装した場合、あなたが実装したす 637 べてのメソッドはあなたのアプリケーションの context object に継承されます。プラグ 638 インはグローバルなネームスペースをけがします。あなたはほんとうにそうしたいときに 639 だけそうするべきです。 685 Catalystのプラグインにしてしまうと、自分で実装したり、インポートしたり継承したりしたすべてのメソッドがアプリのコンテキストオブジェクトから利用できるようになってしまいます。プラグインはグローバルなネームスペースを汚染してしまうのですが、そういうことをしてもいいのは、どうしても必要な場合のみ。 640 686 641 687 Often, developers design extensions as plugins because they need to … … 646 692 object via L<Catalyst::Component/"ACCEPT_CONTEXT($c, @args)">. 647 693 694 プラグインにしてしまう理由としてよく言われるのがコンテキストオブジェクトをいじる必要がある、ということ。stashや、request/responseオブジェクトを使いたいという言い訳をよく聞きますが、こういうのはふつうのCatalystコンポーネント(つまり、モデルやビュー、コントローラ)として実装してもまったく問題ありません。現在のコンテキストオブジェクトはL<Catalyst::Component/"ACCEPT_CONTEXT($c, @args)">で受け取れます。 695 648 696 When is a plugin suited to your task? Your code needs to be a 649 697 plugin to act upon or alter specific parts of Catalyst's request … … 651 699 C<finalize_*> stages, you won't get around a plugin. 652 700 701 プラグインが適切な場合? Catalystがリクエストを処理するサイクルの一部に手を入れる場合はプラグインにする必要があります。C<prepare_*>とかC<finalize_*>をラップする必要があるならプラグインにせざるをえない、ということです。 702 653 703 Another valid target for a plugin architecture are things that 654 704 B<really> have to be globally available, like sessions or 655 705 authentication. 706 707 もうひとつプラグインにしてもいいのは、B<本当に>どこからでも利用できないと困る、セッションとか認証など。 656 708 657 709 B<Please do not> release Catalyst extensions as plugins only to … … 660 712 your code only influences those parts of the application where it is 661 713 needed, and namespace clashes and conflicts are ruled out. 714 715 単になにかの機能をアプリ全体で利用したいからというだけの理由でプラグインにするのはB<やめてください>。コントローラのベースクラスのようにもっとスコープの小さなものにして影響の及ぶ範囲を必要なところのみに限り、ネームスペースの衝突などが起こらないようにしましょう。 662 716 663 717 The implementation is pretty easy. Your plugin will be inserted in the … … 671 725 implementation (excuse the lame class name, it's just an example): 672 726 673 プラグインの実装は簡単なようにみえます。あなたのプラグインは Catalyst の継承ツリー 674 の上にはいります。これによりあなたは、Catalyst のリクエストライフサイクルの挙動を 675 変えることができます。あなたが定義したりあなたのパッケージに import したメソッド 676 は、すべてアプリケーションとコンテキストオブジェクトにはえます。例としてあなたが 677 Catalyst に uri_for の返り値が undef だったとき警告をだすプラグインをつくったとし 678 ましょう。(中略)(アホみたいなクラス名ですいません。これは例なので勘弁してね) 727 実装の仕方はとても簡単。プラグインはアプリの継承リストの、Catalyst本体より優先順位の高いところに追加されていきます(だからリクエストのライフサイクルの挙動を変更できるわけです)。プラグインで宣言したメソッド、パッケージ内にインポートしたメソッドはすべてアプリから、またコンテキストオブジェクトから利用できるようになります。たとえば、uri_forが未定義値を返すたびに警告を出させたいとしましょう(たとえばアクションチェーンのキャプチャの数が間違っていた場合などに知らせてほしいわけです)。こういうのはこんなにシンプルに実装できます(クラス名がださいのはサンプルだからということでご勘弁) 679 728 680 729 package Catalyst::Plugin::UriforUndefWarning; … … 695 744 value. 696 745 697 これは Catalyst の C<uri_for> メソッドをうわがきし、undef がかえってきたら警告を 698 ログに吐きだします。 699 700 =head2 COMPONENT() をつかってコンポーネントを生成する(Factory components with COMPONENT()) 746 これで、CatalystのC<uri_for>メソッドがオーバーライドされて、未定義値を返した引数を含むC<warn>ログが出るようになります。 747 748 =head2 Factory components with COMPONENT() 749 750 COMPONENT() をつかってコンポーネントを生成する 701 751 702 752 Every component inheriting from L<Catalyst::Component> contains a … … 707 757 class' C<new> method to return the component object. 708 758 709 L<Catalyst::Component> を継承しているすべてのコンポーネントは C<COMPONENT> メソッ 710 ドをもっています。 759 L<Catalyst::Component>を継承しているコンポーネントにはかならずC<COMPONENT>というメソッドがあります。これはアプリの起動時にC<setup_components>がコンポーネントオブジェクトを初期化するときに使うもの。デフォルトではコンポーネント自身のC<config>とアプリ全体のC<config>をマージして、コンポーネントクラスのC<new>を呼び、コンポーネントオブジェクトを返すようになっています。 711 760 712 761 You can override this method and do and return whatever you want. … … 714 763 C<COMPONENT> method to merge the configuration of your component. 715 764 765 このメソッドも、オーバーライドすれば好きなものを返すようにできます。ただし、その場合はL<Class::C3>を使ってもとのC<COMPONENT>メソッドに処理を送り、コンポーネントの設定をマージするようにしてください。 766 716 767 Here is a stub C<COMPONENT> method: 768 769 C<COMPONENT>メソッドのスタブはこんな感じ。 717 770 718 771 package CatalystX::Component::Foo; … … 736 789 the controller's configuration. 737 790 791 引数は、コンポーネントのクラス名、そのコンポーネントを使うアプリケーションのクラス名、コントローラの設定が入っているハッシュリファレンスです。 792 738 793 You are free to re-bless the object, instantiate a whole other 739 794 component or really do anything compatible with Catalyst's 740 795 expectations on a component. 741 796 797 オブジェクトをblessしなおすのでも、ほかのコンポーネントのインスタンスをつくるのでも、とにかくCatalystがコンポーネントに期待する条件を満たしているなら本当に何をしてもかまいません。 798 742 799 For more information, please see L<Catalyst::Component/"COMPONENT($c,$arguments)">. 743 800 801 詳しくはL<Catalyst::Component/"COMPONENT($c,$arguments)">をどうぞ。 802 744 803 =head1 SEE ALSO 745 804 … … 751 810 752 811 Jonathan Rockway C<< <jrockway@cpan.org> >> 812 813 =head1 TRANSLATORS 814 815 tokuhirom 816 817 charsbar 753 818 754 819 =head1 LICENSE AND COPYRIGHT … … 758 823 759 824 =cut 825
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)