root/docs/cat-ja/Catalyst/Manual/ExtendingCatalyst.pod @ 13143

Revision 13143, 29.4 kB (checked in by tokuhirom, 5 years ago)

本気barさんにやっていただく流れなのでこれにて終了

Line 
1=head1 名前(NAME)
2
3Catalyst::Manual::ExtendingCatalyst - フレームワークを拡張する
4
5=head1 概要(DESCRIPTION)
6
7This document will provide you with access points, techniques and best
8practices to extend the L<Catalyst> framework, or to find more elegant
9ways to abstract and use your own code.
10
11このドキュメントでは Catalyst を拡張する方法やどうやってエレガントにあなたのコー
12ドを抽象化するかについて論じます。
13
14The design of Catalyst is such that the framework itself should not
15get in your way. There are many entry points to alter or extend
16Catalyst's behaviour, and this can be confusing. This document is
17written to help you understand the possibilities, current practices
18and their consequences.
19
20Catalyst はいろんな方法で拡張できるので、あなたは混乱しているかもしれません。この
21ドキュメントではそのあたりの詳細を論じます。
22
23Please read the L<BEST PRACTICES> section before deciding on a design,
24especially if you plan to release your code to CPAN. The Catalyst
25developer and user communities, which B<you are part of>, will benefit
26most if we all work together and coordinate.
27
28あなたのコードを CPAN にうpするまえに、とりあえず L<BEST PRACTICES> の章をよみま
29しょう。 Catalyst の開発者とユーザコミュニティはあなたとともにあります。
30
31If you are unsure on an implementation or have an idea you would like
32to have RFC'ed, it surely is a good idea to send your questions and
33suggestions to the Catalyst mailing list (See L<Catalyst/SUPPORT>)
34and/or come to the C<#catalyst> channel on the C<irc.perl.org>
35network. You might also want to refer to those places for research to
36see if a module doing what you're trying to implement already
37exists. This might give you a solution to your problem or a basis for
38starting.
39
40あなたがなにか実装にまつわるアイディアをもっているのであれば、Catalyst の ML,
41IRC などで話しかけてください。
42
43=head1 ベストプラクティス(BEST PRACTICES)
44
45During Catalyst's early days, it was common to write plugins to
46provide functionality application wide. Since then, Catalyst has
47become a lot more flexible and powerful. It soon became a best
48practice to use some other form of abstraction or interface, to keep
49the scope of its influence as close as possible to where it belongs.
50
51Catalyst が若かりしころ、複数アプリにまたがる機能はプラグインにするのがよいとされ
52えいましたが、現在ではもっとフレキシブルでパワフルな方法があります。
53
54For those in a hurry, here's a quick checklist of some fundamental
55points. If you are going to read the whole thing anyway, you can jump
56forward to L</Namespaces>.
57
58もし君がめっちゃいそいでいるのなら、以下に必須のポイントに関するクイックチェック
59リストを容易したからそれだけでもよんでいきたまえ。もし君がまったりとこの文書を全
60部読むつもりなら L</Namespaces> に進む。
61
62=head2 3分間チェックリスト(Quick Checklist)
63
64=over
65
66=item C<CatalystX::*> というネームスペースをつかいましょう(Use the C<CatalystX::*> namespace if you can!)
67
68If your extension isn't a Model, View, Controller, Plugin, or Engine,
69it's best to leave it out of the C<Catalyst::> namespace.  Use
70<CatalystX::> instead.
71
72もしあなたの拡張が Model でも View でも Controller でも Plugin でも Engine でもな
73ければ、それは C<Catalyst::> というネームスペースにおくべきではありません。
74C<CatalystX::> をかわりにつかってください。
75
76=item プラグインはつくらない(どうしてもつくらなきゃいけない場合をのぞいて)!(Don't make it a plugin unless you have to!)
77
78A plugin should be careful since it's overriding Catalyst internals.
79If your plugin doesn't really need to muck with the internals, make it a
80base Controller or Model.
81
82プラギンは Catalyst の内部をうわがきしちゃうので、注意してね!もしチミのプラグイン
83が、内部を上書きしたいんでなければ、Controller か Model にしてね!
84
85=item コミュニティがあるから利用しちゃおう!(There's a community. Use it!)
86
87There are many experienced developers in the Catalyst community,
88there's always the IRC channel and the mailing list to discuss things.
89
90Catalyst には IRC も ML もあるから、どんどん利用しちゃおう!
91
92=item テストとドキュメンテーションはしっかりね!(Add tests and documentation!)
93
94This gives a stable basis for contribution, and even more importantly,
95builds trust. The easiest way is a test application. See
96L<Catalyst::Manual::Tutorial::Testing> for more information.
97
98あたりまえのことだけど、テストとドキュメンテーションをしない人はお尻ペンペンだよ!
99
100=back
101
102=head2 ネームスペース(Namespaces)
103
104While some core extensions (engines, plugins, etc.) have to be placed
105in the C<Catalyst::*> namespace, the Catalyst core would like to ask
106developers to use the C<CatalystX::*> namespace if possible.
107
108コアの拡張(engine や plugin とか)は、C<Catalyst::*> におくべきだけど、そういうの
109つくるときは開発者に相談してからにしよう。できることなら C<CatalystX::*> におこう。
110
111(訳注: CPAN にアップロードする場合、相談してからやらないと mst に痛烈に DIS られます)
112
113When you try to put a base class for a C<Model>, C<View> or
114C<Controller> directly under your C<MyApp> directory as, for example,
115C<MyApp::Controller::Foo>, you will have the problem that Catalyst
116will try to load that base class as a component of your
117application. The solution is simple: Use another namespace. Common
118ones are C<MyApp::Base::Controller::*> or C<MyApp::ControllerBase::*>
119as examples.
120
121=head2 それをシンプルなモジュールにすることはできませんか?(Can it be a simple module?)
122
123Sometimes you want to use functionality in your application that
124doesn't require the framework at all. Remember that Catalyst is just
125Perl and you always can just C<use> a module. If you have application
126specific code that doesn't need the framework, there is no problem in
127putting it in your C<MyApp::*> namespace. Just don't put it in
128C<Model>, C<Controller> or C<View>, because that would make Catalyst
129try to load them as components.
130
131Catalyst はたんなる Perl であることを思いだしてください。C<use> でいつでもモジュー
132ルをつかえるんですよ。フレームワークと連携することが必要ないアプリケーション専用
133のコードであれば、C<MyApp::*> というネームスペースをつかってください。C<Model>,
134C<Controller>, C<View> というネームスペースにはおかないでください。このネームスペー
135スにおくと Catalyst がコンポーネントとしてロードしちゃいまっせ。
136
137Writing a generic component that only works with Catalyst is wasteful
138of your time.  Try writing a plain perl module, and then a small bit
139of glue that integrates it with Catalyst.  See
140L<Catalyst::Model::DBIC::Schema|Catalyst::Model::DBIC::Schema> for a
141module that takes the approach.  The advantage here is that your
142"Catalyst" DBIC schema works perfectly outside of Catalyst, making
143testing (and command-line scripts) a breeze.  The actual Catalyst
144Model is just a few lines of glue that makes working with the schema
145convenient.
146
147Catalyst に依存した一般的なコンポーネントをつくることは、あなたの時間を無駄に浪費
148させます。素の Perl モジュールを書くことを検討してください。そして、Catalyst とは
149ほんのちょっとの連携コードで連携させてください。このような方法論でつくられたモ
150ジュールの代表例は Catalyst::Model::DBIC::Schema ですので参考にしてください。この
151方法のよさは、DBIC のスキーマが完全に Catalyst の外でうごいているということです。
152こうすることによって、テストが楽になり、コマンドラインスクリプトも簡単に書けます。
153現実の Catalyst の Model は、ほんとにちょっとの連携コードで便利につかえるようにつ
154なぎこまれてるのだ。
155
156If you want the thinnest interface possible, take a look at
157L<Catalyst::Model::Adaptor|Catalyst::Model::Adaptor>.
158
159もし、薄いインターフェースで連携できるんなら Catalyst::Model::Adaptor でつなぎこ
160むのがよいです。
161
162=head2 継承とメソッドのうわがき。(Inheritance and overriding methods)
163
164While Catalyst itself is still based on L<NEXT> (for multiple
165inheritance), extension developers are encouraged to use L<Class::C3>,
166which is what Catalyst will be switching to in some point in the
167future.
168
169When overriding a method, keep in mind that some day additionally
170arguments may be provided to the method, if the last parameter is not
171a flat list. It is thus better to override a method by shifting the
172invocant off of C<@_> and assign the rest of the used arguments, so
173you can pass your complete arguments to the original method via C<@_>:
174
175  use Class::C3; ...
176
177  sub foo { my $self = shift;
178            my ($bar, $baz) = @_; # ...  return
179            $self->next::method(@_); }
180
181If you would do the common
182
183  my ($self, $foo, $bar) = @_;
184
185you'd have to use a much uglier construct to ensure that all arguments
186will be passed along and the method is future proof:
187
188  $self->next::method(@_[ 1 .. $#_ ]);
189
190=head2 テストとドキュメンテーション(Tests and documentation)
191
192When you release your module to the CPAN, proper documentation and at
193least a basic test suite (which means more than pod or even just
194C<use_ok>, sorry) gives people a good base to contribute to the
195module.  It also shows that you care for your users. If you would like
196your module to become a recommended addition, these things will prove
197invaluable.
198
199CPAN にモジュールをリリースするにあたっては、きちんとしたドキュメンテーションと、
200テストスィーツ(use_ok してりゃいいってもんじゃないよ)を提供してくださいな。
201
202If you're just getting started, try using
203L<CatalystX::Starter|CatalystX::Starter> to generate some example
204tests for your module.
205
206もし君が、あたらしくつくりはじめるんなら CatalystX::Starter をつかってみてくださ
207いな。テストの例がはいっているよ。
208
209=head2 メンテナンス(Maintenance)
210
211In planning to release a module to the community (Catalyst or CPAN and
212Perl), you should consider if you have the resources to keep it up to
213date, including fixing bugs and accepting contributions.
214
215If you're not sure about this, you can always ask in the proper
216Catalyst or Perl channels if someone else might be interested in the
217project, and would jump in as co-maintainer.
218
219A public repository can further ease interaction with the
220community. Even read only access enables people to provide you with
221patches to your current development version. subversion, SVN and SVK,
222are broadly preferred in the Catalyst community.
223
224If you're developing a Catalyst extension, please consider asking the
225core team for space in Catalyst's own subversion repository. You can
226get in touch about this via IRC or the Catalyst developers mailing
227list.
228
229=head2 コンテキストオブジェクト(The context object)
230
231Sometimes you want to get a hold of the context object in a component
232that was created on startup time, where no context existed yet. Often
233this is about the model reading something out of the stash or other
234context information (current language, for example).
235
236If you use the context object in your component you have tied it to an
237existing request.  This means that you might get into problems when
238you try to use the component (e.g. the model - the most common case)
239outside of Catalyst, for example in cronjobs.
240
241A stable solution to this problem is to design the Catalyst model
242separately from the underlying model logic. Let's take
243L<Catalyst::Model::DBIC::Schema> as an example. You can create a
244schema outside of Catalyst that knows nothing about the web. This kind
245of design ensures encapsulation and makes development and maintenance
246a whole lot easier. The you use the aforementioned model to tie your
247schema to your application. This gives you a C<MyApp::DBIC> (the name
248is of course just an example) model as well as
249C<MyApp::DBIC::TableName> models to access your result sources
250directly.
251
252By creating such a thin layer between the actual model and the
253Catalyst application, the schema itself is not at all tied to any
254application and the layer in-between can access the model's API using
255information from the context object.
256
257A Catalyst component accesses the context object at request time with
258L<Catalyst::Component/"ACCEPT_CONTEXT($c, @args)">.
259
260=head1 設定(CONFIGURATION)
261
262The application has to interact with the extension with some
263configuration. There is of course again more than one way to do it.
264
265=head2 アトリビュート(Attributes)
266
267You can specify any valid Perl attribute on Catalyst actions you like.
268(See L<attributes/"Syntax of Attribute Lists"> for a description of
269what is valid.) These will be available on the C<Catalyst::Action>
270instance via its C<attributes> accessor. To give an example, this
271action:
272
273  sub foo : Local Bar('Baz') {
274      my ($self, $c) = @_;
275      my $attributes =
276      $self->action_for('foo')->attributes;
277      $c->res->body($attributes->{Bar}[0] );
278  }
279
280will set the response body to C<Baz>. The values always come in an
281array reference. As you can see, you can use attributes to configure
282your actions. You can specify or alter these attributes via
283L</"Component Configuration">, or even react on them as soon as
284Catalyst encounters them by providing your own L<component base
285class|/"Component Base Classes">.
286
287=head2 カスタムアクセサをつくる(Creating custom accessors)
288
289L<Catalyst::Component> uses L<Class::Accessor::Fast> for accessor
290creation. Please refer to the modules documentation for usage
291information.
292
293L<Catalyst::Component> はアクセサをつくるのに L<Class::Accessor::Fast> をつかって
294います。
295
296=head2 コンポーネントの設定(Component configuration)
297
298At creation time, the class configuration of your component (the one
299available via C<$self-E<gt>config>) will be merged with possible
300configuration settings from the applications configuration (either
301directly or via config file).  This is then stored in the controller
302object's hash reference. So, if you read possible configurations like:
303
304  my $model_name = $controller->{model_name};
305
306you will get the right value. The C<config> accessor always only
307contains the original class configuration and must not be used for
308component configuration.
309
310You are advised to create accessors on your component class for your
311configuration values. This is good practice and makes it easier to
312capture configuration key typos. You can do this with the
313C<mk_ro_accessors> method provided to L<Catalyst::Component> via
314L<Class::Accessor::Fast>:
315
316  use base 'Catalyst::Controller';
317  __PACKAGE__->mk_ro_accessors('model_name');
318  ...
319  my $model_name = $controller->model_name;
320
321=head1 実装(IMPLEMENTATION)
322
323This part contains the technical details of various implementation
324methods. Please read the L</"BEST PRACTICES"> before you start your
325implementation, if you haven't already.
326
327=head2 Actionクラス(Action classes)
328
329Usually, your action objects are of the class L<Catalyst::Action>.
330You can override this with the C<ActionClass> attribute to influence
331execution and/or dispatching of the action. A widely used example of
332this is L<Catalyst::Action::RenderView>, which is used in every newly
333created Catalyst application in your root controller:
334
335  sub end : ActionClass('RenderView') { }
336
337Usually, you want to override the C<execute> and/or the C<match>
338method. The execute method of the action will naturally call the
339methods code. You can surround this by overriding the method in a
340subclass:
341
342  package Catalyst::Action::MyFoo; use strict;
343
344  use Class::C3; use base 'Catalyst::Action';
345
346  sub execute {
347      my $self = shift;
348      my ($controller, $c, @args) = @_;
349      # put your 'before' code here
350      my $r = $self->next::method(@_);
351      # put your 'after' code here
352      return $r;
353  }
354  1;
355
356We are using L<Class::C3> to re-dispatch to the original C<execute> method
357in the L<Catalyst::Action> class.
358
359The Catalyst dispatcher handles an incoming request and, depending
360upon the dispatch type, will call the appropriate target or chain.
361From time to time it asks the actions themselves, or through the
362controller, if they would match the current request. That's what the
363C<match> method does.  So by overriding this, you can change on what
364the action will match and add new matching criteria.
365
366For example, the action class below will make the action only match on
367Mondays:
368
369  package Catalyst::Action::OnlyMondays; use strict;
370
371  use Class::C3;
372  use base 'Catalyst::Action';
373
374  sub match {
375      my $self = shift;
376      return 0 if ( localtime(time) )[6] == 1;
377      return $self->next::method(@_);
378   }
379  1;
380
381And this is how we'd use it:
382
383  sub foo: Local ActionClass('OnlyMondays') {
384      my ($self, $c) = @_;
385      $c->res->body('I feel motivated!');
386  }
387
388If you are using action classes often or have some specific base
389classes that you want to specify more conveniently, you can implement
390a component base class providing an attribute handler.
391
392For further information on action classes, please refer to
393L<Catalyst::Action> and L<Catalyst::Manual::Actions>.
394
395=head2 コンポーネントなクラス(Component base classes)
396
397Many L<Catalyst::Plugin> that were written in Catalyst's early days
398should really have been just controller base classes. With such a
399class, you could provide functionality scoped to a single controller,
400not polluting the global namespace in the context object.
401
402Catalyst がうまれたての頃に多くの L<Catalyst::Plugin> が書かれました。
403
404You can provide regular Perl methods in a base class as well as
405actions which will be inherited to the subclass. Please refer to
406L</Controllers> for an example of this.
407
408You can introduce your own attributes by specifying a handler method
409in the controller base. For example, to use a C<FullClass> attribute
410to specify a fully qualified action class name, you could use the
411following implementation. Note, however, that this functionality is
412already provided via the C<+> prefix for action classes. A simple
413
414シンプルな
415
416  sub foo : Local ActionClass('+MyApp::Action::Bar') { ... }
417
418will use C<MyApp::Action::Bar> as action class.
419
420は、C<MyApp::Action::Bar> を Action クラスとしてつかいます。
421
422  package MyApp::Base::Controller::FullClass; use strict; use base
423  'Catalyst::Controller';
424
425  sub _parse_FullClass_attr {
426      my ($self, $app_class, $action_name, $value, $attrs) = @_;
427      return( ActionClass => $value );
428  }
429  1;
430
431Note that the full line of arguments is only provided for completeness
432sake. We could use this attribute in a subclass like any other
433Catalyst attribute:
434
435  package MyApp::Controller::Foo;
436  use strict;
437  use base 'MyApp::Base::Controller::FullClass';
438
439  sub foo : Local FullClass('MyApp::Action::Bar') { ... }
440
441  1;
442
443=head2 コントローラ(Controllers)
444
445Many things can happen in controllers, and it often improves
446maintainability to abstract some of the code out into reusable base
447classes.
448
449You can provide usual Perl methods that will be available via your
450controller object, or you can even define Catalyst actions which will
451be inherited by the subclasses. Consider this controller base class:
452
453  package MyApp::Base::Controller::ModelBase;
454  use strict;
455  use base 'Catalyst::Controller';
456
457  sub list : Chained('base') PathPart('') Args(0) {
458      my ($self, $c) = @_;
459      my $model = $c->model( $self->{model_name} );
460      my $condition = $self->{model_search_condition} || {};
461      my $attrs = $self->{model_search_attrs} || {};
462      $c->stash(rs => $model->search($condition, $attrs);
463      }
464
465  sub load : Chained('base') PathPart('') CaptureArgs(1) {
466      my ($self, $c, $id) = @_;
467      my $model = $c->model( $self->{model_name} );
468      $c->stash(row => $model->find($id));
469      }
470  1;
471
472This example implements two simple actions. The C<list> action chains
473to a (currently non-existent) C<base> action and puts a result-set
474into the stash taking a configured C<model_name> as well as a search
475condition and attributes. This action is a
476L<chained|Catalyst::DispatchType::Chained> endpoint. The other action,
477called C< load > is a chain midpoint that takes one argument. It takes
478the value as an ID and loads the row from the configured model. Please
479not that the above code is simplified for clarity. It misses error
480handling, input validation, and probably other things.
481
482The class above is not very useful on its own, but we can combine it
483with some custom actions by sub-classing it:
484
485  package MyApp::Controller::Foo;
486  use strict;
487  use base 'MyApp::Base::Controller::ModelBase';
488
489  __PACKAGE__->config( model_name => 'DB::Foo',
490                       model_search_condition=> { is_active => 1 },
491                       model_search_attrs => { order_by => 'name' },
492                   );
493
494  sub base : Chained PathPart('foo') CaptureArgs(0) { }
495
496  sub view : Chained('load') Args(0) {
497      my ($self, $c) = @_;
498      my $row = $c->stash->{row};
499      $c->res->body(join ': ', $row->name,
500      $row->description); }
501  1;
502
503This class uses the formerly created controller as a base
504class. First, we see the configurations that were used in the parent
505class. Next comes the C<base> action, where everything chains off of.
506
507Note that inherited actions act like they were declared in your
508controller itself. You can therefor call them just by their name in
509C<forward>s, C<detaches> and C<Chained(..)> specifications. This is an
510important part of what makes this technique so useful.
511
512The new C<view> action ties itself to the C<load> action specified in
513the base class and outputs the loaded row's C<name> and C<description>
514columns. The controller C<MyApp::Controller::Foo> now has these
515publicly available paths:
516
517=over
518
519=item /foo
520
521Will call the controller's C<base>, then the base classes C<list>
522action.
523
524=item /foo/$id/view
525
526First, the controller's C<base> will be called, then it will C<load>
527the row with the corresponding C<$id>. After that, C<view> will
528display some fields out of the object.
529
530=back
531
532=head2 モデルとビュー(Models and Views)
533
534If the functionality you'd like to add is really a data-set that you
535want to manipulate, for example internal document types, images,
536files, it might be better suited as a model.
537
538The same applies for views. If your code handles representation or
539deals with the applications interface and should be universally
540available, it could be a perfect candidate for a view.
541
542Please implement a C<process> method in your views. This method will
543be called by Catalyst if it is asked to forward to a component without
544a specified action. Note that C<process> is B<not a Catalyst action>
545but a simple Perl method.
546
547You are also encouraged to implement a C<render> method corresponding
548with the one in L<Catalyst::View::TT>. This has proven invaluable,
549because people can use your view for much more fine-grained content
550generation.
551
552Here is some example code for a fictional view:
553
554  package CatalystX::View::MyView;
555  use strict;
556  use base 'Catalyst::View';
557
558  sub process {
559      my ($self, $c) = @_;
560      my $template = $c->stash->{template};
561      my $content = $self->render($c, $template, $c->stash);
562      $c->res->body( $content );
563  }
564
565  sub render {
566      my ($self, $c, $template, $args) = @_;
567      # prepare content here
568      return $content;
569  }
570  1;
571
572=head2 プラグイン(Plugins)
573
574The first thing to say about plugins is that if you're not sure if
575your module should be a plugin, it probably shouldn't. It once was
576common to add features to Catalyst by writing plugins that provide
577accessors to said functionality. As Catalyst grew more popular, it
578became obvious that this qualifies as bad practice.
579
580まずもって、あなたがプラグインをつくろうとおもっている場合、十中八九プラグインを
581つくるべきではありません。
582
583By designing your module as a Catalyst plugin, every method you
584implement, import or inherit will be available via your applications
585context object.  A plugin pollutes the global namespace, and you
586should be only doing that when you really need to.
587
588あなたのモジュールを Catalyst のプラグインとして実装した場合、あなたが実装したす
589べてのメソッドはあなたのアプリケーションの context object に継承されます。プラグ
590インはグローバルなネームスペースをけがします。あなたはほんとうにそうしたいときに
591だけそうするべきです。
592
593Often, developers design extensions as plugins because they need to
594get hold of the context object. Either to get at the stash or
595request/response objects are the widely spread reasons. It is,
596however, perfectly possible to implement a regular Catalyst component
597(read: model, view or controller) that receives the current context
598object via L<Catalyst::Component/"ACCEPT_CONTEXT($c, @args)">.
599
600When is a plugin suited to your task? Your code needs to be a
601plugin to act upon or alter specific parts of Catalyst's request
602lifecycle. If your functionality needs to wrap some C<prepare_*> or
603C<finalize_*> stages, you won't get around a plugin.
604
605Another valid target for a plugin architecture are things that
606B<really> have to be globally available, like sessions or
607authentication.
608
609B<Please do not> release Catalyst extensions as plugins only to
610provide some functionality application wide. Design it as a controller
611base class or another suiting technique with a smaller scope, so that
612your code only influences those parts of the application where it is
613needed, and namespace clashes and conflicts are ruled out.
614
615The implementation is pretty easy. Your plugin will be inserted in the
616application's inheritance list, above Catalyst itself. You can by this
617alter Catalyst's request lifecycle behaviour. Every method you
618declare, every import in your package will be available as method on
619the application and the context object. As an example, let's say you
620want Catalyst to warn you every time uri_for returned an undefined
621value, for example because you specified the wrong number of captures
622for the targeted action chain. You could do this with this simple
623implementation (excuse the lame class name, it's just an example):
624
625プラグインの実装は簡単なようにみえます。あなたのプラグインは Catalyst の継承ツリー
626の上にはいります。これによりあなたは、Catalyst のリクエストライフサイクルの挙動を
627変えることができます。あなたが定義したりあなたのパッケージに import したメソッド
628は、すべてアプリケーションとコンテキストオブジェクトにはえます。例としてあなたが
629Catalyst に uri_for の返り値が undef だったとき警告をだすプラグインをつくったとし
630ましょう。(中略)(アホみたいなクラス名ですいません。これは例なので勘弁してね)
631
632  package Catalyst::Plugin::UriforUndefWarning;
633  use strict;
634  use Class::C3;
635
636  sub uri_for {
637      my $c = shift;
638      my $uri = $c->next::method(@_);
639      $c->log->warn( 'uri_for returned undef for:', join(', ', @_), );
640      return $uri;
641  }
642
643  1;
644
645This would override Catalyst's C<uri_for> method and emit a C<warn>
646log entry containing the arguments that led to the undefined return
647value.
648
649これは Catalyst の C<uri_for> メソッドをうわがきし、undef がかえってきたら警告を
650ログに吐きだします。
651
652=head2 COMPONENT() をつかってコンポーネントを生成する(Factory components with COMPONENT())
653
654Every component inheriting from L<Catalyst::Component> contains a
655C<COMPONENT> method. It is used on application startup by
656C<setup_components> to instantiate the component object for the
657Catalyst application. By default, this will merge the components own
658C<config>uration with the application wide overrides and call the
659class' C<new> method to return the component object.
660
661L<Catalyst::Component> を継承しているすべてのコンポーネントは C<COMPONENT> メソッ
662ドをもっています。
663
664You can override this method and do and return whatever you want.
665However, you should use L<Class::C3> to forward to the original
666C<COMPONENT> method to merge the configuration of your component.
667
668Here is a stub C<COMPONENT> method:
669
670  package CatalystX::Component::Foo;
671  use strict;
672  use base 'Catalyst::Component';
673
674  use Class::C3;
675
676  sub COMPONENT {
677      my $class = shift;
678      my ($app_class, $config) = @_;
679
680      # do things here before instantiation my
681      $obj = $self->next::method(@_);
682      # do things to object after instantiation
683      return $object;
684  }
685
686The arguments are the class name of the component, the class name of
687the application instantiating the component, and a hash reference with
688the controller's configuration.
689
690You are free to re-bless the object, instantiate a whole other
691component or really do anything compatible with Catalyst's
692expectations on a component.
693
694For more information, please see L<Catalyst::Component/"COMPONENT($c,$arguments)">.
695
696=head1 SEE ALSO
697
698L<Catalyst>, L<Catalyst::Manual::Actions>, L<Catalyst::Component>
699
700=head1 AUTHOR
701
702Robert Sedlacek C<< <rs@474.at> >>
703
704Jonathan Rockway C<< <jrockway@cpan.org> >>
705
706=head1 LICENSE AND COPYRIGHT
707
708This document is free, you can redistribute it and/or modify it under
709the same terms as Perl itself.
710
711=cut
Note: See TracBrowser for help on using the browser.