e6a9f4d8e7bf03dbd1cb4eb579966bb79a62e0c1
[catagits/Catalyst-Runtime.git] / lib / Catalyst.pm
1 package Catalyst;
2
3 use Moose;
4 use Moose::Meta::Class ();
5 extends 'Catalyst::Component';
6 use Moose::Util qw/find_meta/;
7 use B::Hooks::EndOfScope ();
8 use Catalyst::Exception;
9 use Catalyst::Exception::Detach;
10 use Catalyst::Exception::Go;
11 use Catalyst::Log;
12 use Catalyst::Request;
13 use Catalyst::Request::Upload;
14 use Catalyst::Response;
15 use Catalyst::Utils;
16 use Catalyst::Controller;
17 use Data::OptList;
18 use Devel::InnerPackage ();
19 use File::stat;
20 use Module::Pluggable::Object ();
21 use Text::SimpleTable ();
22 use Path::Class::Dir ();
23 use Path::Class::File ();
24 use URI ();
25 use URI::http;
26 use URI::https;
27 use Tree::Simple qw/use_weak_refs/;
28 use Tree::Simple::Visitor::FindByUID;
29 use Class::C3::Adopt::NEXT;
30 use List::MoreUtils qw/uniq/;
31 use attributes;
32 use utf8;
33 use Carp qw/croak carp shortmess/;
34
35 BEGIN { require 5.008004; }
36
37 has stack => (is => 'ro', default => sub { [] });
38 has stash => (is => 'rw', default => sub { {} });
39 has state => (is => 'rw', default => 0);
40 has stats => (is => 'rw');
41 has action => (is => 'rw');
42 has counter => (is => 'rw', default => sub { {} });
43 has request => (is => 'rw', default => sub { $_[0]->request_class->new({}) }, required => 1, lazy => 1);
44 has response => (is => 'rw', default => sub { $_[0]->response_class->new({}) }, required => 1, lazy => 1);
45 has namespace => (is => 'rw');
46
47 sub depth { scalar @{ shift->stack || [] }; }
48 sub comp { shift->component(@_) }
49
50 sub req {
51     my $self = shift; return $self->request(@_);
52 }
53 sub res {
54     my $self = shift; return $self->response(@_);
55 }
56
57 # For backwards compatibility
58 sub finalize_output { shift->finalize_body(@_) };
59
60 # For statistics
61 our $COUNT     = 1;
62 our $START     = time;
63 our $RECURSION = 1000;
64 our $DETACH    = Catalyst::Exception::Detach->new;
65 our $GO        = Catalyst::Exception::Go->new;
66
67 #I imagine that very few of these really need to be class variables. if any.
68 #maybe we should just make them attributes with a default?
69 __PACKAGE__->mk_classdata($_)
70   for qw/container components arguments dispatcher engine log dispatcher_class
71   engine_class context_class request_class response_class stats_class
72   setup_finished/;
73
74 __PACKAGE__->dispatcher_class('Catalyst::Dispatcher');
75 __PACKAGE__->engine_class('Catalyst::Engine::CGI');
76 __PACKAGE__->request_class('Catalyst::Request');
77 __PACKAGE__->response_class('Catalyst::Response');
78 __PACKAGE__->stats_class('Catalyst::Stats');
79
80 # Remember to update this in Catalyst::Runtime as well!
81
82 our $VERSION = '5.80032';
83
84 sub import {
85     my ( $class, @arguments ) = @_;
86
87     # We have to limit $class to Catalyst to avoid pushing Catalyst upon every
88     # callers @ISA.
89     return unless $class eq 'Catalyst';
90
91     my $caller = caller();
92     return if $caller eq 'main';
93
94     my $meta = Moose::Meta::Class->initialize($caller);
95     unless ( $caller->isa('Catalyst') ) {
96         my @superclasses = ($meta->superclasses, $class, 'Catalyst::Controller');
97         $meta->superclasses(@superclasses);
98     }
99     # Avoid possible C3 issues if 'Moose::Object' is already on RHS of MyApp
100     $meta->superclasses(grep { $_ ne 'Moose::Object' } $meta->superclasses);
101
102     unless( $meta->has_method('meta') ){
103         if ($Moose::VERSION >= 1.15) {
104             $meta->_add_meta_method('meta');
105         }
106         else {
107             $meta->add_method(meta => sub { Moose::Meta::Class->initialize("${caller}") } );
108         }
109     }
110
111     $caller->arguments( [@arguments] );
112     $caller->setup_home;
113 }
114
115 sub _application { $_[0] }
116
117 =head1 NAME
118
119 Catalyst - The Elegant MVC Web Application Framework
120
121 =head1 SYNOPSIS
122
123 See the L<Catalyst::Manual> distribution for comprehensive
124 documentation and tutorials.
125
126     # Install Catalyst::Devel for helpers and other development tools
127     # use the helper to create a new application
128     catalyst.pl MyApp
129
130     # add models, views, controllers
131     script/myapp_create.pl model MyDatabase DBIC::Schema create=static dbi:SQLite:/path/to/db
132     script/myapp_create.pl view MyTemplate TT
133     script/myapp_create.pl controller Search
134
135     # built in testserver -- use -r to restart automatically on changes
136     # --help to see all available options
137     script/myapp_server.pl
138
139     # command line testing interface
140     script/myapp_test.pl /yada
141
142     ### in lib/MyApp.pm
143     use Catalyst qw/-Debug/; # include plugins here as well
144
145     ### In lib/MyApp/Controller/Root.pm (autocreated)
146     sub foo : Global { # called for /foo, /foo/1, /foo/1/2, etc.
147         my ( $self, $c, @args ) = @_; # args are qw/1 2/ for /foo/1/2
148         $c->stash->{template} = 'foo.tt'; # set the template
149         # lookup something from db -- stash vars are passed to TT
150         $c->stash->{data} =
151           $c->model('Database::Foo')->search( { country => $args[0] } );
152         if ( $c->req->params->{bar} ) { # access GET or POST parameters
153             $c->forward( 'bar' ); # process another action
154             # do something else after forward returns
155         }
156     }
157
158     # The foo.tt TT template can use the stash data from the database
159     [% WHILE (item = data.next) %]
160         [% item.foo %]
161     [% END %]
162
163     # called for /bar/of/soap, /bar/of/soap/10, etc.
164     sub bar : Path('/bar/of/soap') { ... }
165
166     # called for all actions, from the top-most controller downwards
167     sub auto : Private {
168         my ( $self, $c ) = @_;
169         if ( !$c->user_exists ) { # Catalyst::Plugin::Authentication
170             $c->res->redirect( '/login' ); # require login
171             return 0; # abort request and go immediately to end()
172         }
173         return 1; # success; carry on to next action
174     }
175
176     # called after all actions are finished
177     sub end : Private {
178         my ( $self, $c ) = @_;
179         if ( scalar @{ $c->error } ) { ... } # handle errors
180         return if $c->res->body; # already have a response
181         $c->forward( 'MyApp::View::TT' ); # render template
182     }
183
184     ### in MyApp/Controller/Foo.pm
185     # called for /foo/bar
186     sub bar : Local { ... }
187
188     # called for /blargle
189     sub blargle : Global { ... }
190
191     # an index action matches /foo, but not /foo/1, etc.
192     sub index : Private { ... }
193
194     ### in MyApp/Controller/Foo/Bar.pm
195     # called for /foo/bar/baz
196     sub baz : Local { ... }
197
198     # first Root auto is called, then Foo auto, then this
199     sub auto : Private { ... }
200
201     # powerful regular expression paths are also possible
202     sub details : Regex('^product/(\w+)/details$') {
203         my ( $self, $c ) = @_;
204         # extract the (\w+) from the URI
205         my $product = $c->req->captures->[0];
206     }
207
208 See L<Catalyst::Manual::Intro> for additional information.
209
210 =head1 DESCRIPTION
211
212 Catalyst is a modern framework for making web applications without the
213 pain usually associated with this process. This document is a reference
214 to the main Catalyst application. If you are a new user, we suggest you
215 start with L<Catalyst::Manual::Tutorial> or L<Catalyst::Manual::Intro>.
216
217 See L<Catalyst::Manual> for more documentation.
218
219 Catalyst plugins can be loaded by naming them as arguments to the "use
220 Catalyst" statement. Omit the C<Catalyst::Plugin::> prefix from the
221 plugin name, i.e., C<Catalyst::Plugin::My::Module> becomes
222 C<My::Module>.
223
224     use Catalyst qw/My::Module/;
225
226 If your plugin starts with a name other than C<Catalyst::Plugin::>, you can
227 fully qualify the name by using a unary plus:
228
229     use Catalyst qw/
230         My::Module
231         +Fully::Qualified::Plugin::Name
232     /;
233
234 Special flags like C<-Debug> and C<-Engine> can also be specified as
235 arguments when Catalyst is loaded:
236
237     use Catalyst qw/-Debug My::Module/;
238
239 The position of plugins and flags in the chain is important, because
240 they are loaded in the order in which they appear.
241
242 The following flags are supported:
243
244 =head2 -Debug
245
246 Enables debug output. You can also force this setting from the system
247 environment with CATALYST_DEBUG or <MYAPP>_DEBUG. The environment
248 settings override the application, with <MYAPP>_DEBUG having the highest
249 priority.
250
251 This sets the log level to 'debug' and enables full debug output on the
252 error screen. If you only want the latter, see L<< $c->debug >>.
253
254 =head2 -Engine
255
256 Forces Catalyst to use a specific engine. Omit the
257 C<Catalyst::Engine::> prefix of the engine name, i.e.:
258
259     use Catalyst qw/-Engine=CGI/;
260
261 =head2 -Home
262
263 Forces Catalyst to use a specific home directory, e.g.:
264
265     use Catalyst qw[-Home=/usr/mst];
266
267 This can also be done in the shell environment by setting either the
268 C<CATALYST_HOME> environment variable or C<MYAPP_HOME>; where C<MYAPP>
269 is replaced with the uppercased name of your application, any "::" in
270 the name will be replaced with underscores, e.g. MyApp::Web should use
271 MYAPP_WEB_HOME. If both variables are set, the MYAPP_HOME one will be used.
272
273 If none of these are set, Catalyst will attempt to automatically detect the
274 home directory. If you are working in a development envirnoment, Catalyst
275 will try and find the directory containing either Makefile.PL, Build.PL or
276 dist.ini. If the application has been installed into the system (i.e.
277 you have done C<make install>), then Catalyst will use the path to your
278 application module, without the .pm extension (ie, /foo/MyApp if your
279 application was installed at /foo/MyApp.pm)
280
281 =head2 -Log
282
283     use Catalyst '-Log=warn,fatal,error';
284
285 Specifies a comma-delimited list of log levels.
286
287 =head2 -Stats
288
289 Enables statistics collection and reporting.
290
291    use Catalyst qw/-Stats=1/;
292
293 You can also force this setting from the system environment with CATALYST_STATS
294 or <MYAPP>_STATS. The environment settings override the application, with
295 <MYAPP>_STATS having the highest priority.
296
297 Stats are also enabled if L<< debugging |/"-Debug" >> is enabled.
298
299 =head1 METHODS
300
301 =head2 INFORMATION ABOUT THE CURRENT REQUEST
302
303 =head2 $c->action
304
305 Returns a L<Catalyst::Action> object for the current action, which
306 stringifies to the action name. See L<Catalyst::Action>.
307
308 =head2 $c->namespace
309
310 Returns the namespace of the current action, i.e., the URI prefix
311 corresponding to the controller of the current action. For example:
312
313     # in Controller::Foo::Bar
314     $c->namespace; # returns 'foo/bar';
315
316 =head2 $c->request
317
318 =head2 $c->req
319
320 Returns the current L<Catalyst::Request> object, giving access to
321 information about the current client request (including parameters,
322 cookies, HTTP headers, etc.). See L<Catalyst::Request>.
323
324 =head2 REQUEST FLOW HANDLING
325
326 =head2 $c->forward( $action [, \@arguments ] )
327
328 =head2 $c->forward( $class, $method, [, \@arguments ] )
329
330 Forwards processing to another action, by its private name. If you give a
331 class name but no method, C<process()> is called. You may also optionally
332 pass arguments in an arrayref. The action will receive the arguments in
333 C<@_> and C<< $c->req->args >>. Upon returning from the function,
334 C<< $c->req->args >> will be restored to the previous values.
335
336 Any data C<return>ed from the action forwarded to, will be returned by the
337 call to forward.
338
339     my $foodata = $c->forward('/foo');
340     $c->forward('index');
341     $c->forward(qw/Model::DBIC::Foo do_stuff/);
342     $c->forward('View::TT');
343
344 Note that L<< forward|/"$c->forward( $action [, \@arguments ] )" >> implies
345 an C<< eval { } >> around the call (actually
346 L<< execute|/"$c->execute( $class, $coderef )" >> does), thus de-fatalizing
347 all 'dies' within the called action. If you want C<die> to propagate you
348 need to do something like:
349
350     $c->forward('foo');
351     die join "\n", @{ $c->error } if @{ $c->error };
352
353 Or make sure to always return true values from your actions and write
354 your code like this:
355
356     $c->forward('foo') || return;
357
358 Another note is that C<< $c->forward >> always returns a scalar because it
359 actually returns $c->state which operates in a scalar context.
360 Thus, something like:
361
362     return @array;
363
364 in an action that is forwarded to is going to return a scalar,
365 i.e. how many items are in that array, which is probably not what you want.
366 If you need to return an array then return a reference to it,
367 or stash it like so:
368
369     $c->stash->{array} = \@array;
370
371 and access it from the stash.
372
373 Keep in mind that the C<end> method used is that of the caller action. So a C<$c-E<gt>detach> inside a forwarded action would run the C<end> method from the original action requested.
374
375 =cut
376
377 sub forward { my $c = shift; no warnings 'recursion'; $c->dispatcher->forward( $c, @_ ) }
378
379 =head2 $c->detach( $action [, \@arguments ] )
380
381 =head2 $c->detach( $class, $method, [, \@arguments ] )
382
383 =head2 $c->detach()
384
385 The same as L<< forward|/"$c->forward( $action [, \@arguments ] )" >>, but
386 doesn't return to the previous action when processing is finished.
387
388 When called with no arguments it escapes the processing chain entirely.
389
390 =cut
391
392 sub detach { my $c = shift; $c->dispatcher->detach( $c, @_ ) }
393
394 =head2 $c->visit( $action [, \@captures, \@arguments ] )
395
396 =head2 $c->visit( $class, $method, [, \@captures, \@arguments ] )
397
398 Almost the same as L<< forward|/"$c->forward( $action [, \@arguments ] )" >>,
399 but does a full dispatch, instead of just calling the new C<$action> /
400 C<< $class->$method >>. This means that C<begin>, C<auto> and the method
401 you go to are called, just like a new request.
402
403 In addition both C<< $c->action >> and C<< $c->namespace >> are localized.
404 This means, for example, that C<< $c->action >> methods such as
405 L<name|Catalyst::Action/name>, L<class|Catalyst::Action/class> and
406 L<reverse|Catalyst::Action/reverse> return information for the visited action
407 when they are invoked within the visited action.  This is different from the
408 behavior of L<< forward|/"$c->forward( $action [, \@arguments ] )" >>, which
409 continues to use the $c->action object from the caller action even when
410 invoked from the callee.
411
412 C<< $c->stash >> is kept unchanged.
413
414 In effect, L<< visit|/"$c->visit( $action [, \@captures, \@arguments ] )" >>
415 allows you to "wrap" another action, just as it would have been called by
416 dispatching from a URL, while the analogous
417 L<< go|/"$c->go( $action [, \@captures, \@arguments ] )" >> allows you to
418 transfer control to another action as if it had been reached directly from a URL.
419
420 =cut
421
422 sub visit { my $c = shift; $c->dispatcher->visit( $c, @_ ) }
423
424 =head2 $c->go( $action [, \@captures, \@arguments ] )
425
426 =head2 $c->go( $class, $method, [, \@captures, \@arguments ] )
427
428 The relationship between C<go> and
429 L<< visit|/"$c->visit( $action [, \@captures, \@arguments ] )" >> is the same as
430 the relationship between
431 L<< forward|/"$c->forward( $class, $method, [, \@arguments ] )" >> and
432 L<< detach|/"$c->detach( $action [, \@arguments ] )" >>. Like C<< $c->visit >>,
433 C<< $c->go >> will perform a full dispatch on the specified action or method,
434 with localized C<< $c->action >> and C<< $c->namespace >>. Like C<detach>,
435 C<go> escapes the processing of the current request chain on completion, and
436 does not return to its caller.
437
438 @arguments are arguments to the final destination of $action. @captures are
439 arguments to the intermediate steps, if any, on the way to the final sub of
440 $action.
441
442 =cut
443
444 sub go { my $c = shift; $c->dispatcher->go( $c, @_ ) }
445
446 =head2 $c->response
447
448 =head2 $c->res
449
450 Returns the current L<Catalyst::Response> object, see there for details.
451
452 =head2 $c->stash
453
454 Returns a hashref to the stash, which may be used to store data and pass
455 it between components during a request. You can also set hash keys by
456 passing arguments. The stash is automatically sent to the view. The
457 stash is cleared at the end of a request; it cannot be used for
458 persistent storage (for this you must use a session; see
459 L<Catalyst::Plugin::Session> for a complete system integrated with
460 Catalyst).
461
462     $c->stash->{foo} = $bar;
463     $c->stash( { moose => 'majestic', qux => 0 } );
464     $c->stash( bar => 1, gorch => 2 ); # equivalent to passing a hashref
465
466     # stash is automatically passed to the view for use in a template
467     $c->forward( 'MyApp::View::TT' );
468
469 =cut
470
471 around stash => sub {
472     my $orig = shift;
473     my $c = shift;
474     my $stash = $orig->($c);
475     if (@_) {
476         my $new_stash = @_ > 1 ? {@_} : $_[0];
477         croak('stash takes a hash or hashref') unless ref $new_stash;
478         foreach my $key ( keys %$new_stash ) {
479           $stash->{$key} = $new_stash->{$key};
480         }
481     }
482
483     return $stash;
484 };
485
486
487 =head2 $c->error
488
489 =head2 $c->error($error, ...)
490
491 =head2 $c->error($arrayref)
492
493 Returns an arrayref containing error messages.  If Catalyst encounters an
494 error while processing a request, it stores the error in $c->error.  This
495 method should only be used to store fatal error messages.
496
497     my @error = @{ $c->error };
498
499 Add a new error.
500
501     $c->error('Something bad happened');
502
503 =cut
504
505 sub error {
506     my $c = shift;
507     if ( $_[0] ) {
508         my $error = ref $_[0] eq 'ARRAY' ? $_[0] : [@_];
509         croak @$error unless ref $c;
510         push @{ $c->{error} }, @$error;
511     }
512     elsif ( defined $_[0] ) { $c->{error} = undef }
513     return $c->{error} || [];
514 }
515
516
517 =head2 $c->state
518
519 Contains the return value of the last executed action.
520 Note that << $c->state >> operates in a scalar context which means that all
521 values it returns are scalar.
522
523 =head2 $c->clear_errors
524
525 Clear errors.  You probably don't want to clear the errors unless you are
526 implementing a custom error screen.
527
528 This is equivalent to running
529
530     $c->error(0);
531
532 =cut
533
534 sub clear_errors {
535     my $c = shift;
536     $c->error(0);
537 }
538
539 =head2 COMPONENT ACCESSORS
540
541 =head2 $c->controller($name)
542
543 Gets a L<Catalyst::Controller> instance by name.
544
545     $c->controller('Foo')->do_stuff;
546
547 If the name is omitted, will return the controller for the dispatched
548 action.
549
550 If you want to search for controllers, pass in a regexp as the argument.
551
552     # find all controllers that start with Foo
553     my @foo_controllers = $c->controller(qr{^Foo});
554
555
556 =cut
557
558 sub controller {
559     my ( $c, $name, @args ) = @_;
560
561 # FIXME: should this be a Catalyst::Utils method?
562     if (!$name) {
563         my $class  = $c->action->class;
564
565         my $prefix = length Catalyst::Utils::class2classprefix($class);
566
567         # MyApp::Controller::Foo becomes Foo
568         # the + 2 is because of the ::
569         $name = substr $class, $prefix + 2;
570     }
571
572     return $c->container->get_component_from_sub_container( 'controller', $name, $c, @args);
573 }
574
575 =head2 $c->model($name)
576
577 Gets a L<Catalyst::Model> instance by name.
578
579     $c->model('Foo')->do_stuff;
580
581 Any extra arguments are directly passed to ACCEPT_CONTEXT.
582
583 If the name is omitted, it will look for
584  - a model object in $c->stash->{current_model_instance}, then
585  - a model name in $c->stash->{current_model}, then
586  - a config setting 'default_model', or
587  - check if there is only one model, and return it if that's the case.
588
589 If you want to search for models, pass in a regexp as the argument.
590
591     # find all models that start with Foo
592     my @foo_models = $c->model(qr{^Foo});
593
594 =cut
595
596 sub model {
597     my ( $c, $name, @args ) = @_;
598
599     if (ref $c && !$name) {
600         return $c->stash->{current_model_instance}
601             if $c->stash->{current_model_instance};
602
603         $name = $c->stash->{current_model}
604             if $c->stash->{current_model};
605     }
606
607     return $c->container->get_component_from_sub_container( 'model', $name, $c, @args);
608 }
609
610
611 =head2 $c->view($name)
612
613 Gets a L<Catalyst::View> instance by name.
614
615     $c->view('Foo')->do_stuff;
616
617 Any extra arguments are directly passed to ACCEPT_CONTEXT.
618
619 If the name is omitted, it will look for
620  - a view object in $c->stash->{current_view_instance}, then
621  - a view name in $c->stash->{current_view}, then
622  - a config setting 'default_view', or
623  - check if there is only one view, and return it if that's the case.
624
625 If you want to search for views, pass in a regexp as the argument.
626
627     # find all views that start with Foo
628     my @foo_views = $c->view(qr{^Foo});
629
630 =cut
631
632 sub view {
633     my ( $c, $name, @args ) = @_;
634
635     if (ref $c && !$name) {
636         return $c->stash->{current_view_instance}
637             if $c->stash->{current_view_instance};
638
639         $name = $c->stash->{current_view}
640             if $c->stash->{current_view};
641     }
642
643     return $c->container->get_component_from_sub_container( 'view', $name, $c, @args);
644 }
645
646 =head2 $c->controllers
647
648 Returns the available names which can be passed to $c->controller
649
650 =cut
651
652 sub controllers {
653     my ( $c ) = @_;
654     return $c->container->get_sub_container('controller')->get_service_list;
655 }
656
657 =head2 $c->models
658
659 Returns the available names which can be passed to $c->model
660
661 =cut
662
663 sub models {
664     my ( $c ) = @_;
665     return $c->container->get_sub_container('model')->get_service_list;
666 }
667
668
669 =head2 $c->views
670
671 Returns the available names which can be passed to $c->view
672
673 =cut
674
675 sub views {
676     my ( $c ) = @_;
677     return $c->container->get_sub_container('view')->get_service_list;
678 }
679
680 =head2 $c->comp($name)
681
682 =head2 $c->component($name)
683
684 Gets a component object by name. This method is not recommended,
685 unless you want to get a specific component by full
686 class. C<< $c->controller >>, C<< $c->model >>, and C<< $c->view >>
687 should be used instead.
688
689 If C<$name> is a regexp, a list of components matched against the full
690 component name will be returned.
691
692 =cut
693
694 sub component {
695     my ( $c, $component, @args ) = @_;
696
697     if ( $component ) {
698         my ($type, $name) = _get_component_type_name($component);
699
700         if ($type && $c->container->has_sub_container($type)) {
701             my $container = $c->container->get_sub_container($type);
702
703             if( !ref $component && $container->has_service($name) ) {
704                 return $container->get_component( $name, $c, @args );
705             }
706
707             return $container->get_component_regexp( $name, $c, @args );
708         }
709
710         if (ref $component) {
711             for my $subcontainer_name (qw/model view controller/) {
712                 my $subcontainer = $c->container->get_sub_container($subcontainer_name);
713                 my @components   = $subcontainer->get_service_list;
714                 my @result       = grep { m{$component} } @components;
715
716                 return map { $subcontainer->get_component( $_, $c, @args ) } @result
717                     if @result;
718             }
719         }
720
721         # FIXME: I probably shouldn't be doing this
722         # I'm keeping it temporarily for things like $c->comp('MyApp')
723         return $c->components->{$component}
724             if exists $c->components->{$component} and !@args;
725
726         $c->log->warn("Looking for '$component', but nothing was found.");
727
728         # I would expect to return an empty list here, but that breaks back-compat
729     }
730
731     # fallback
732     return sort keys %{ $c->components };
733 }
734
735 =head2 CLASS DATA AND HELPER CLASSES
736
737 =head2 $c->config
738
739 Returns or takes a hashref containing the application's configuration.
740
741     __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } );
742
743 You can also use a C<YAML>, C<XML> or L<Config::General> config file
744 like C<myapp.conf> in your applications home directory. See
745 L<Catalyst::Plugin::ConfigLoader>.
746
747 =head3 Cascading configuration
748
749 The config method is present on all Catalyst components, and configuration
750 will be merged when an application is started. Configuration loaded with
751 L<Catalyst::Plugin::ConfigLoader> takes precedence over other configuration,
752 followed by configuration in your top level C<MyApp> class. These two
753 configurations are merged, and then configuration data whose hash key matches a
754 component name is merged with configuration for that component.
755
756 The configuration for a component is then passed to the C<new> method when a
757 component is constructed.
758
759 For example:
760
761     MyApp->config({ 'Model::Foo' => { bar => 'baz', overrides => 'me' } });
762     MyApp::Model::Foo->config({ quux => 'frob', overrides => 'this' });
763
764 will mean that C<MyApp::Model::Foo> receives the following data when
765 constructed:
766
767     MyApp::Model::Foo->new({
768         bar => 'baz',
769         quux => 'frob',
770         overrides => 'me',
771     });
772
773 It's common practice to use a Moose attribute
774 on the receiving component to access the config value.
775
776     package MyApp::Model::Foo;
777
778     use Moose;
779
780     # this attr will receive 'baz' at construction time
781     has 'bar' => (
782         is  => 'rw',
783         isa => 'Str',
784     );
785
786 You can then get the value 'baz' by calling $c->model('Foo')->bar
787 (or $self->bar inside code in the model).
788
789 B<NOTE:> you MUST NOT call C<< $self->config >> or C<< __PACKAGE__->config >>
790 as a way of reading config within your code, as this B<will not> give you the
791 correctly merged config back. You B<MUST> take the config values supplied to
792 the constructor and use those instead.
793
794 =cut
795
796 around config => sub {
797     my $orig = shift;
798     my $c = shift;
799
800     croak('Setting config after setup has been run is not allowed.')
801         if ( @_ and $c->setup_finished );
802
803     $c->$orig(@_);
804 };
805
806 =head2 $c->log
807
808 Returns the logging object instance. Unless it is already set, Catalyst
809 sets this up with a L<Catalyst::Log> object. To use your own log class,
810 set the logger with the C<< __PACKAGE__->log >> method prior to calling
811 C<< __PACKAGE__->setup >>.
812
813  __PACKAGE__->log( MyLogger->new );
814  __PACKAGE__->setup;
815
816 And later:
817
818     $c->log->info( 'Now logging with my own logger!' );
819
820 Your log class should implement the methods described in
821 L<Catalyst::Log>.
822
823
824 =head2 $c->debug
825
826 Returns 1 if debug mode is enabled, 0 otherwise.
827
828 You can enable debug mode in several ways:
829
830 =over
831
832 =item By calling myapp_server.pl with the -d flag
833
834 =item With the environment variables MYAPP_DEBUG, or CATALYST_DEBUG
835
836 =item The -Debug option in your MyApp.pm
837
838 =item By declaring C<sub debug { 1 }> in your MyApp.pm.
839
840 =back
841
842 The first three also set the log level to 'debug'.
843
844 Calling C<< $c->debug(1) >> has no effect.
845
846 =cut
847
848 sub debug { 0 }
849
850 =head2 $c->dispatcher
851
852 Returns the dispatcher instance. See L<Catalyst::Dispatcher>.
853
854 =head2 $c->engine
855
856 Returns the engine instance. See L<Catalyst::Engine>.
857
858
859 =head2 UTILITY METHODS
860
861 =head2 $c->path_to(@path)
862
863 Merges C<@path> with C<< $c->config->{home} >> and returns a
864 L<Path::Class::Dir> object. Note you can usually use this object as
865 a filename, but sometimes you will have to explicitly stringify it
866 yourself by calling the C<< ->stringify >> method.
867
868 For example:
869
870     $c->path_to( 'db', 'sqlite.db' );
871
872 =cut
873
874 sub path_to {
875     my ( $c, @path ) = @_;
876     my $path = Path::Class::Dir->new( $c->config->{home}, @path );
877     if ( -d $path ) { return $path }
878     else { return Path::Class::File->new( $c->config->{home}, @path ) }
879 }
880
881 =head2 $c->plugin( $name, $class, @args )
882
883 Helper method for plugins. It creates a class data accessor/mutator and
884 loads and instantiates the given class.
885
886     MyApp->plugin( 'prototype', 'HTML::Prototype' );
887
888     $c->prototype->define_javascript_functions;
889
890 B<Note:> This method of adding plugins is deprecated. The ability
891 to add plugins like this B<will be removed> in a Catalyst 5.81.
892 Please do not use this functionality in new code.
893
894 =cut
895
896 sub plugin {
897     my ( $class, $name, $plugin, @args ) = @_;
898
899     # See block comment in t/unit_core_plugin.t
900     $class->log->warn(qq/Adding plugin using the ->plugin method is deprecated, and will be removed in Catalyst 5.81/);
901
902     $class->_register_plugin( $plugin, 1 );
903
904     eval { $plugin->import };
905     $class->mk_classdata($name);
906     my $obj;
907     eval { $obj = $plugin->new(@args) };
908
909     if ($@) {
910         Catalyst::Exception->throw( message =>
911               qq/Couldn't instantiate instant plugin "$plugin", "$@"/ );
912     }
913
914     $class->$name($obj);
915     $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/)
916       if $class->debug;
917 }
918
919 =head2 MyApp->setup
920
921 Initializes the dispatcher and engine, loads any plugins, and loads the
922 model, view, and controller components. You may also specify an array
923 of plugins to load here, if you choose to not load them in the C<use
924 Catalyst> line.
925
926     MyApp->setup;
927     MyApp->setup( qw/-Debug/ );
928
929 =cut
930
931 sub setup {
932     my ( $class, @arguments ) = @_;
933     croak('Running setup more than once')
934         if ( $class->setup_finished );
935
936     unless ( $class->isa('Catalyst') ) {
937
938         Catalyst::Exception->throw(
939             message => qq/'$class' does not inherit from Catalyst/ );
940     }
941
942     if ( $class->arguments ) {
943         @arguments = ( @arguments, @{ $class->arguments } );
944     }
945
946     # Process options
947     my $flags = {};
948
949     foreach (@arguments) {
950
951         if (/^-Debug$/) {
952             $flags->{log} =
953               ( $flags->{log} ) ? 'debug,' . $flags->{log} : 'debug';
954         }
955         elsif (/^-(\w+)=?(.*)$/) {
956             $flags->{ lc $1 } = $2;
957         }
958         else {
959             push @{ $flags->{plugins} }, $_;
960         }
961     }
962
963     $class->setup_config();
964     $class->setup_home( delete $flags->{home} );
965
966     $class->setup_log( delete $flags->{log} );
967     $class->setup_plugins( delete $flags->{plugins} );
968     $class->setup_dispatcher( delete $flags->{dispatcher} );
969     $class->setup_engine( delete $flags->{engine} );
970     $class->setup_stats( delete $flags->{stats} );
971
972     for my $flag ( sort keys %{$flags} ) {
973
974         if ( my $code = $class->can( 'setup_' . $flag ) ) {
975             &$code( $class, delete $flags->{$flag} );
976         }
977         else {
978             $class->log->warn(qq/Unknown flag "$flag"/);
979         }
980     }
981
982     eval { require Catalyst::Devel; };
983     if( !$@ && $ENV{CATALYST_SCRIPT_GEN} && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::Devel::CATALYST_SCRIPT_GEN ) ) {
984         $class->log->warn(<<"EOF");
985 You are running an old script!
986
987   Please update by running (this will overwrite existing files):
988     catalyst.pl -force -scripts $class
989
990   or (this will not overwrite existing files):
991     catalyst.pl -scripts $class
992
993 EOF
994     }
995
996     if ( $class->debug ) {
997         my @plugins = map { "$_  " . ( $_->VERSION || '' ) } $class->registered_plugins;
998
999         if (@plugins) {
1000             my $column_width = Catalyst::Utils::term_width() - 6;
1001             my $t = Text::SimpleTable->new($column_width);
1002             $t->row($_) for @plugins;
1003             $class->log->debug( "Loaded plugins:\n" . $t->draw . "\n" );
1004         }
1005
1006         my $dispatcher = $class->dispatcher;
1007         my $engine     = $class->engine;
1008         my $home       = $class->config->{home};
1009
1010         $class->log->debug(sprintf(q/Loaded dispatcher "%s"/, blessed($dispatcher)));
1011         $class->log->debug(sprintf(q/Loaded engine "%s"/, blessed($engine)));
1012
1013         $home
1014           ? ( -d $home )
1015           ? $class->log->debug(qq/Found home "$home"/)
1016           : $class->log->debug(qq/Home "$home" doesn't exist/)
1017           : $class->log->debug(q/Couldn't find home/);
1018     }
1019
1020     # Call plugins setup, this is stupid and evil.
1021     # Also screws C3 badly on 5.10, hack to avoid.
1022     {
1023         no warnings qw/redefine/;
1024         local *setup = sub { };
1025         $class->setup unless $Catalyst::__AM_RESTARTING;
1026     }
1027
1028     # Initialize our data structure
1029     $class->components( {} );
1030
1031     $class->setup_components;
1032
1033     if ( $class->debug ) {
1034         my $column_width = Catalyst::Utils::term_width() - 8 - 9;
1035         my $t = Text::SimpleTable->new( [ $column_width, 'Class' ], [ 8, 'Type' ] );
1036         for my $comp ( sort keys %{ $class->components } ) {
1037             my $type = ref $class->components->{$comp} ? 'instance' : 'class';
1038             $t->row( $comp, $type );
1039         }
1040         $class->log->debug( "Loaded components:\n" . $t->draw . "\n" )
1041           if ( keys %{ $class->components } );
1042     }
1043
1044     # Add our self to components, since we are also a component
1045     if( $class->isa('Catalyst::Controller') ){
1046       $class->components->{$class} = $class;
1047     }
1048
1049     $class->setup_actions;
1050
1051     if ( $class->debug ) {
1052         my $name = $class->config->{name} || 'Application';
1053         $class->log->info("$name powered by Catalyst $Catalyst::VERSION");
1054     }
1055
1056     # Make sure that the application class becomes immutable at this point,
1057     B::Hooks::EndOfScope::on_scope_end {
1058         return if $@;
1059         my $meta = Class::MOP::get_metaclass_by_name($class);
1060         if (
1061             $meta->is_immutable
1062             && ! { $meta->immutable_options }->{replace_constructor}
1063             && (
1064                    $class->isa('Class::Accessor::Fast')
1065                 || $class->isa('Class::Accessor')
1066             )
1067         ) {
1068             warn "You made your application class ($class) immutable, "
1069                 . "but did not inline the\nconstructor. "
1070                 . "This will break catalyst, as your app \@ISA "
1071                 . "Class::Accessor(::Fast)?\nPlease pass "
1072                 . "(replace_constructor => 1)\nwhen making your class immutable.\n";
1073         }
1074         $meta->make_immutable(
1075             replace_constructor => 1,
1076         ) unless $meta->is_immutable;
1077     };
1078
1079     if ($class->config->{case_sensitive}) {
1080         $class->log->warn($class . "->config->{case_sensitive} is set.");
1081         $class->log->warn("This setting is deprecated and planned to be removed in Catalyst 5.81.");
1082     }
1083
1084     $class->setup_finalize;
1085     # Should be the last thing we do so that user things hooking
1086     # setup_finalize can log..
1087     $class->log->_flush() if $class->log->can('_flush');
1088     return 1; # Explicit return true as people have __PACKAGE__->setup as the last thing in their class. HATE.
1089 }
1090
1091 =head2 $app->setup_finalize
1092
1093 A hook to attach modifiers to. This method does not do anything except set the
1094 C<setup_finished> accessor.
1095
1096 Applying method modifiers to the C<setup> method doesn't work, because of quirky things done for plugin setup.
1097
1098 Example:
1099
1100     after setup_finalize => sub {
1101         my $app = shift;
1102
1103         ## do stuff here..
1104     };
1105
1106 =cut
1107
1108 sub setup_finalize {
1109     my ($class) = @_;
1110     $class->setup_finished(1);
1111 }
1112
1113 =head2 $c->uri_for( $path?, @args?, \%query_values? )
1114
1115 =head2 $c->uri_for( $action, \@captures?, @args?, \%query_values? )
1116
1117 Constructs an absolute L<URI> object based on the application root, the
1118 provided path, and the additional arguments and query parameters provided.
1119 When used as a string, provides a textual URI.  If you need more flexibility
1120 than this (i.e. the option to provide relative URIs etc.) see
1121 L<Catalyst::Plugin::SmartURI>.
1122
1123 If no arguments are provided, the URI for the current action is returned.
1124 To return the current action and also provide @args, use
1125 C<< $c->uri_for( $c->action, @args ) >>.
1126
1127 If the first argument is a string, it is taken as a public URI path relative
1128 to C<< $c->namespace >> (if it doesn't begin with a forward slash) or
1129 relative to the application root (if it does). It is then merged with
1130 C<< $c->request->base >>; any C<@args> are appended as additional path
1131 components; and any C<%query_values> are appended as C<?foo=bar> parameters.
1132
1133 If the first argument is a L<Catalyst::Action> it represents an action which
1134 will have its path resolved using C<< $c->dispatcher->uri_for_action >>. The
1135 optional C<\@captures> argument (an arrayref) allows passing the captured
1136 variables that are needed to fill in the paths of Chained and Regex actions;
1137 once the path is resolved, C<uri_for> continues as though a path was
1138 provided, appending any arguments or parameters and creating an absolute
1139 URI.
1140
1141 The captures for the current request can be found in
1142 C<< $c->request->captures >>, and actions can be resolved using
1143 C<< Catalyst::Controller->action_for($name) >>. If you have a private action
1144 path, use C<< $c->uri_for_action >> instead.
1145
1146   # Equivalent to $c->req->uri
1147   $c->uri_for($c->action, $c->req->captures,
1148       @{ $c->req->args }, $c->req->params);
1149
1150   # For the Foo action in the Bar controller
1151   $c->uri_for($c->controller('Bar')->action_for('Foo'));
1152
1153   # Path to a static resource
1154   $c->uri_for('/static/images/logo.png');
1155
1156 =cut
1157
1158 sub uri_for {
1159     my ( $c, $path, @args ) = @_;
1160
1161     if (blessed($path) && $path->isa('Catalyst::Controller')) {
1162         $path = $path->path_prefix;
1163         $path =~ s{/+\z}{};
1164         $path .= '/';
1165     }
1166
1167     undef($path) if (defined $path && $path eq '');
1168
1169     my $params =
1170       ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} );
1171
1172     carp "uri_for called with undef argument" if grep { ! defined $_ } @args;
1173     foreach my $arg (@args) {
1174         utf8::encode($arg) if utf8::is_utf8($arg);
1175         $arg =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go;
1176     }
1177
1178     if ( blessed($path) ) { # action object
1179         s|/|%2F|g for @args;
1180         my $captures = [ map { s|/|%2F|g; $_; }
1181                         ( scalar @args && ref $args[0] eq 'ARRAY'
1182                          ? @{ shift(@args) }
1183                          : ()) ];
1184
1185         foreach my $capture (@$captures) {
1186             utf8::encode($capture) if utf8::is_utf8($capture);
1187             $capture =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go;
1188         }
1189
1190         my $action = $path;
1191         $path = $c->dispatcher->uri_for_action($action, $captures);
1192         if (not defined $path) {
1193             $c->log->debug(qq/Can't find uri_for action '$action' @$captures/)
1194                 if $c->debug;
1195             return undef;
1196         }
1197         $path = '/' if $path eq '';
1198     }
1199
1200     unshift(@args, $path);
1201
1202     unless (defined $path && $path =~ s!^/!!) { # in-place strip
1203         my $namespace = $c->namespace;
1204         if (defined $path) { # cheesy hack to handle path '../foo'
1205            $namespace =~ s{(?:^|/)[^/]+$}{} while $args[0] =~ s{^\.\./}{};
1206         }
1207         unshift(@args, $namespace || '');
1208     }
1209
1210     # join args with '/', or a blank string
1211     my $args = join('/', grep { defined($_) } @args);
1212     $args =~ s/\?/%3F/g; # STUPID STUPID SPECIAL CASE
1213     $args =~ s!^/+!!;
1214     my $base = $c->req->base;
1215     my $class = ref($base);
1216     $base =~ s{(?<!/)$}{/};
1217
1218     my $query = '';
1219
1220     if (my @keys = keys %$params) {
1221       # somewhat lifted from URI::_query's query_form
1222       $query = '?'.join('&', map {
1223           my $val = $params->{$_};
1224           s/([;\/?:@&=+,\$\[\]%])/$URI::Escape::escapes{$1}/go;
1225           s/ /+/g;
1226           my $key = $_;
1227           $val = '' unless defined $val;
1228           (map {
1229               my $param = "$_";
1230               utf8::encode( $param ) if utf8::is_utf8($param);
1231               # using the URI::Escape pattern here so utf8 chars survive
1232               $param =~ s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go;
1233               $param =~ s/ /+/g;
1234               "${key}=$param"; } ( ref $val eq 'ARRAY' ? @$val : $val ));
1235       } @keys);
1236     }
1237
1238     my $res = bless(\"${base}${args}${query}", $class);
1239     $res;
1240 }
1241
1242 =head2 $c->uri_for_action( $path, \@captures?, @args?, \%query_values? )
1243
1244 =head2 $c->uri_for_action( $action, \@captures?, @args?, \%query_values? )
1245
1246 =over
1247
1248 =item $path
1249
1250 A private path to the Catalyst action you want to create a URI for.
1251
1252 This is a shortcut for calling C<< $c->dispatcher->get_action_by_path($path)
1253 >> and passing the resulting C<$action> and the remaining arguments to C<<
1254 $c->uri_for >>.
1255
1256 You can also pass in a Catalyst::Action object, in which case it is passed to
1257 C<< $c->uri_for >>.
1258
1259 Note that although the path looks like a URI that dispatches to the wanted action, it is not a URI, but an internal path to that action.
1260
1261 For example, if the action looks like:
1262
1263  package MyApp::Controller::Users;
1264
1265  sub lst : Path('the-list') {}
1266
1267 You can use:
1268
1269  $c->uri_for_action('/users/lst')
1270
1271 and it will create the URI /users/the-list.
1272
1273 =back
1274
1275 =cut
1276
1277 sub uri_for_action {
1278     my ( $c, $path, @args ) = @_;
1279     my $action = blessed($path)
1280       ? $path
1281       : $c->dispatcher->get_action_by_path($path);
1282     unless (defined $action) {
1283       croak "Can't find action for path '$path'";
1284     }
1285     return $c->uri_for( $action, @args );
1286 }
1287
1288 =head2 $c->welcome_message
1289
1290 Returns the Catalyst welcome HTML page.
1291
1292 =cut
1293
1294 sub welcome_message {
1295     my $c      = shift;
1296     my $name   = $c->config->{name};
1297     my $logo   = $c->uri_for('/static/images/catalyst_logo.png');
1298     my $prefix = Catalyst::Utils::appprefix( ref $c );
1299     $c->response->content_type('text/html; charset=utf-8');
1300     return <<"EOF";
1301 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1302     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1303 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
1304     <head>
1305     <meta http-equiv="Content-Language" content="en" />
1306     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1307         <title>$name on Catalyst $VERSION</title>
1308         <style type="text/css">
1309             body {
1310                 color: #000;
1311                 background-color: #eee;
1312             }
1313             div#content {
1314                 width: 640px;
1315                 margin-left: auto;
1316                 margin-right: auto;
1317                 margin-top: 10px;
1318                 margin-bottom: 10px;
1319                 text-align: left;
1320                 background-color: #ccc;
1321                 border: 1px solid #aaa;
1322             }
1323             p, h1, h2 {
1324                 margin-left: 20px;
1325                 margin-right: 20px;
1326                 font-family: verdana, tahoma, sans-serif;
1327             }
1328             a {
1329                 font-family: verdana, tahoma, sans-serif;
1330             }
1331             :link, :visited {
1332                     text-decoration: none;
1333                     color: #b00;
1334                     border-bottom: 1px dotted #bbb;
1335             }
1336             :link:hover, :visited:hover {
1337                     color: #555;
1338             }
1339             div#topbar {
1340                 margin: 0px;
1341             }
1342             pre {
1343                 margin: 10px;
1344                 padding: 8px;
1345             }
1346             div#answers {
1347                 padding: 8px;
1348                 margin: 10px;
1349                 background-color: #fff;
1350                 border: 1px solid #aaa;
1351             }
1352             h1 {
1353                 font-size: 0.9em;
1354                 font-weight: normal;
1355                 text-align: center;
1356             }
1357             h2 {
1358                 font-size: 1.0em;
1359             }
1360             p {
1361                 font-size: 0.9em;
1362             }
1363             p img {
1364                 float: right;
1365                 margin-left: 10px;
1366             }
1367             span#appname {
1368                 font-weight: bold;
1369                 font-size: 1.6em;
1370             }
1371         </style>
1372     </head>
1373     <body>
1374         <div id="content">
1375             <div id="topbar">
1376                 <h1><span id="appname">$name</span> on <a href="http://catalyst.perl.org">Catalyst</a>
1377                     $VERSION</h1>
1378              </div>
1379              <div id="answers">
1380                  <p>
1381                  <img src="$logo" alt="Catalyst Logo" />
1382                  </p>
1383                  <p>Welcome to the  world of Catalyst.
1384                     This <a href="http://en.wikipedia.org/wiki/MVC">MVC</a>
1385                     framework will make web development something you had
1386                     never expected it to be: Fun, rewarding, and quick.</p>
1387                  <h2>What to do now?</h2>
1388                  <p>That really depends  on what <b>you</b> want to do.
1389                     We do, however, provide you with a few starting points.</p>
1390                  <p>If you want to jump right into web development with Catalyst
1391                     you might want to start with a tutorial.</p>
1392 <pre>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Tutorial.pod">Catalyst::Manual::Tutorial</a></code>
1393 </pre>
1394 <p>Afterwards you can go on to check out a more complete look at our features.</p>
1395 <pre>
1396 <code>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Intro.pod">Catalyst::Manual::Intro</a>
1397 <!-- Something else should go here, but the Catalyst::Manual link seems unhelpful -->
1398 </code></pre>
1399                  <h2>What to do next?</h2>
1400                  <p>Next it's time to write an actual application. Use the
1401                     helper scripts to generate <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AController%3A%3A&amp;mode=all">controllers</a>,
1402                     <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AModel%3A%3A&amp;mode=all">models</a>, and
1403                     <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AView%3A%3A&amp;mode=all">views</a>;
1404                     they can save you a lot of work.</p>
1405                     <pre><code>script/${prefix}_create.pl --help</code></pre>
1406                     <p>Also, be sure to check out the vast and growing
1407                     collection of <a href="http://search.cpan.org/search?query=Catalyst">plugins for Catalyst on CPAN</a>;
1408                     you are likely to find what you need there.
1409                     </p>
1410
1411                  <h2>Need help?</h2>
1412                  <p>Catalyst has a very active community. Here are the main places to
1413                     get in touch with us.</p>
1414                  <ul>
1415                      <li>
1416                          <a href="http://dev.catalyst.perl.org">Wiki</a>
1417                      </li>
1418                      <li>
1419                          <a href="http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst">Mailing-List</a>
1420                      </li>
1421                      <li>
1422                          <a href="irc://irc.perl.org/catalyst">IRC channel #catalyst on irc.perl.org</a>
1423                      </li>
1424                  </ul>
1425                  <h2>In conclusion</h2>
1426                  <p>The Catalyst team hopes you will enjoy using Catalyst as much
1427                     as we enjoyed making it. Please contact us if you have ideas
1428                     for improvement or other feedback.</p>
1429              </div>
1430          </div>
1431     </body>
1432 </html>
1433 EOF
1434 }
1435
1436 =head1 INTERNAL METHODS
1437
1438 These methods are not meant to be used by end users.
1439
1440 =head2 $c->components
1441
1442 Returns a hash of components.
1443
1444 =cut
1445
1446 around components => sub {
1447     my $orig  = shift;
1448     my $class = shift;
1449     my $comps = shift;
1450
1451     return $class->$orig if ( !$comps );
1452
1453 # FIXME: should this ugly kludge exist?
1454     $class->setup_config unless defined $class->container;
1455
1456 # FIXME: should there be a warning here, not to use this accessor to create the components?
1457     my $components = {};
1458
1459     my $containers;
1460     $containers->{$_} = $class->container->get_sub_container($_) for qw(model view controller);
1461
1462     for my $component ( keys %$comps ) {
1463         $components->{ $component } = $comps->{$component};
1464
1465         my ($type, $name) = _get_component_type_name($component);
1466
1467         $containers->{$type}->add_service(Catalyst::IOC::BlockInjection->new( name => $name, block => sub { return $class->setup_component($component) } ));
1468     }
1469
1470     return $class->$orig($components);
1471 };
1472
1473 =head2 $c->context_class
1474
1475 Returns or sets the context class.
1476
1477 =head2 $c->counter
1478
1479 Returns a hashref containing coderefs and execution counts (needed for
1480 deep recursion detection).
1481
1482 =head2 $c->depth
1483
1484 Returns the number of actions on the current internal execution stack.
1485
1486 =head2 $c->dispatch
1487
1488 Dispatches a request to actions.
1489
1490 =cut
1491
1492 sub dispatch { my $c = shift; $c->dispatcher->dispatch( $c, @_ ) }
1493
1494 =head2 $c->dispatcher_class
1495
1496 Returns or sets the dispatcher class.
1497
1498 =head2 $c->dump_these
1499
1500 Returns a list of 2-element array references (name, structure) pairs
1501 that will be dumped on the error page in debug mode.
1502
1503 =cut
1504
1505 sub dump_these {
1506     my $c = shift;
1507     [ Request => $c->req ],
1508     [ Response => $c->res ],
1509     [ Stash => $c->stash ],
1510     [ Config => $c->config ];
1511 }
1512
1513 =head2 $c->engine_class
1514
1515 Returns or sets the engine class.
1516
1517 =head2 $c->execute( $class, $coderef )
1518
1519 Execute a coderef in given class and catch exceptions. Errors are available
1520 via $c->error.
1521
1522 =cut
1523
1524 sub execute {
1525     my ( $c, $class, $code ) = @_;
1526     $class = $c->component($class) || $class;
1527     $c->state(0);
1528
1529     if ( $c->depth >= $RECURSION ) {
1530         my $action = $code->reverse();
1531         $action = "/$action" unless $action =~ /->/;
1532         my $error = qq/Deep recursion detected calling "${action}"/;
1533         $c->log->error($error);
1534         $c->error($error);
1535         $c->state(0);
1536         return $c->state;
1537     }
1538
1539     my $stats_info = $c->_stats_start_execute( $code ) if $c->use_stats;
1540
1541     push( @{ $c->stack }, $code );
1542
1543     no warnings 'recursion';
1544     # N.B. This used to be combined, but I have seen $c get clobbered if so, and
1545     #      I have no idea how, ergo $ret (which appears to fix the issue)
1546     eval { my $ret = $code->execute( $class, $c, @{ $c->req->args } ) || 0; $c->state( $ret ) };
1547
1548     $c->_stats_finish_execute( $stats_info ) if $c->use_stats and $stats_info;
1549
1550     my $last = pop( @{ $c->stack } );
1551
1552     if ( my $error = $@ ) {
1553         if ( blessed($error) and $error->isa('Catalyst::Exception::Detach') ) {
1554             $error->rethrow if $c->depth > 1;
1555         }
1556         elsif ( blessed($error) and $error->isa('Catalyst::Exception::Go') ) {
1557             $error->rethrow if $c->depth > 0;
1558         }
1559         else {
1560             unless ( ref $error ) {
1561                 no warnings 'uninitialized';
1562                 chomp $error;
1563                 my $class = $last->class;
1564                 my $name  = $last->name;
1565                 $error = qq/Caught exception in $class->$name "$error"/;
1566             }
1567             $c->error($error);
1568         }
1569         $c->state(0);
1570     }
1571     return $c->state;
1572 }
1573
1574 sub _stats_start_execute {
1575     my ( $c, $code ) = @_;
1576     my $appclass = ref($c) || $c;
1577     return if ( ( $code->name =~ /^_.*/ )
1578         && ( !$appclass->config->{show_internal_actions} ) );
1579
1580     my $action_name = $code->reverse();
1581     $c->counter->{$action_name}++;
1582
1583     my $action = $action_name;
1584     $action = "/$action" unless $action =~ /->/;
1585
1586     # determine if the call was the result of a forward
1587     # this is done by walking up the call stack and looking for a calling
1588     # sub of Catalyst::forward before the eval
1589     my $callsub = q{};
1590     for my $index ( 2 .. 11 ) {
1591         last
1592         if ( ( caller($index) )[0] eq 'Catalyst'
1593             && ( caller($index) )[3] eq '(eval)' );
1594
1595         if ( ( caller($index) )[3] =~ /forward$/ ) {
1596             $callsub = ( caller($index) )[3];
1597             $action  = "-> $action";
1598             last;
1599         }
1600     }
1601
1602     my $uid = $action_name . $c->counter->{$action_name};
1603
1604     # is this a root-level call or a forwarded call?
1605     if ( $callsub =~ /forward$/ ) {
1606         my $parent = $c->stack->[-1];
1607
1608         # forward, locate the caller
1609         if ( defined $parent && exists $c->counter->{"$parent"} ) {
1610             $c->stats->profile(
1611                 begin  => $action,
1612                 parent => "$parent" . $c->counter->{"$parent"},
1613                 uid    => $uid,
1614             );
1615         }
1616         else {
1617
1618             # forward with no caller may come from a plugin
1619             $c->stats->profile(
1620                 begin => $action,
1621                 uid   => $uid,
1622             );
1623         }
1624     }
1625     else {
1626
1627         # root-level call
1628         $c->stats->profile(
1629             begin => $action,
1630             uid   => $uid,
1631         );
1632     }
1633     return $action;
1634
1635 }
1636
1637 sub _stats_finish_execute {
1638     my ( $c, $info ) = @_;
1639     $c->stats->profile( end => $info );
1640 }
1641
1642 =head2 $c->finalize
1643
1644 Finalizes the request.
1645
1646 =cut
1647
1648 sub finalize {
1649     my $c = shift;
1650
1651     for my $error ( @{ $c->error } ) {
1652         $c->log->error($error);
1653     }
1654
1655     # Allow engine to handle finalize flow (for POE)
1656     my $engine = $c->engine;
1657     if ( my $code = $engine->can('finalize') ) {
1658         $engine->$code($c);
1659     }
1660     else {
1661
1662         $c->finalize_uploads;
1663
1664         # Error
1665         if ( $#{ $c->error } >= 0 ) {
1666             $c->finalize_error;
1667         }
1668
1669         $c->finalize_headers;
1670
1671         # HEAD request
1672         if ( $c->request->method eq 'HEAD' ) {
1673             $c->response->body('');
1674         }
1675
1676         $c->finalize_body;
1677     }
1678
1679     $c->log_response;
1680
1681     if ($c->use_stats) {
1682         my $elapsed = sprintf '%f', $c->stats->elapsed;
1683         my $av = $elapsed == 0 ? '??' : sprintf '%.3f', 1 / $elapsed;
1684         $c->log->info(
1685             "Request took ${elapsed}s ($av/s)\n" . $c->stats->report . "\n" );
1686     }
1687
1688     return $c->response->status;
1689 }
1690
1691 =head2 $c->finalize_body
1692
1693 Finalizes body.
1694
1695 =cut
1696
1697 sub finalize_body { my $c = shift; $c->engine->finalize_body( $c, @_ ) }
1698
1699 =head2 $c->finalize_cookies
1700
1701 Finalizes cookies.
1702
1703 =cut
1704
1705 sub finalize_cookies { my $c = shift; $c->engine->finalize_cookies( $c, @_ ) }
1706
1707 =head2 $c->finalize_error
1708
1709 Finalizes error.
1710
1711 =cut
1712
1713 sub finalize_error { my $c = shift; $c->engine->finalize_error( $c, @_ ) }
1714
1715 =head2 $c->finalize_headers
1716
1717 Finalizes headers.
1718
1719 =cut
1720
1721 sub finalize_headers {
1722     my $c = shift;
1723
1724     my $response = $c->response; #accessor calls can add up?
1725
1726     # Check if we already finalized headers
1727     return if $response->finalized_headers;
1728
1729     # Handle redirects
1730     if ( my $location = $response->redirect ) {
1731         $c->log->debug(qq/Redirecting to "$location"/) if $c->debug;
1732         $response->header( Location => $location );
1733
1734         if ( !$response->has_body ) {
1735             # Add a default body if none is already present
1736             $response->body(
1737                 qq{<html><body><p>This item has moved <a href="$location">here</a>.</p></body></html>}
1738             );
1739         }
1740     }
1741
1742     # Content-Length
1743     if ( defined $response->body && length $response->body && !$response->content_length ) {
1744
1745         # get the length from a filehandle
1746         if ( blessed( $response->body ) && $response->body->can('read') || ref( $response->body ) eq 'GLOB' )
1747         {
1748             my $stat = stat $response->body;
1749             if ( $stat && $stat->size > 0 ) {
1750                 $response->content_length( $stat->size );
1751             }
1752             else {
1753                 $c->log->warn('Serving filehandle without a content-length');
1754             }
1755         }
1756         else {
1757             # everything should be bytes at this point, but just in case
1758             $response->content_length( length( $response->body ) );
1759         }
1760     }
1761
1762     # Errors
1763     if ( $response->status =~ /^(1\d\d|[23]04)$/ ) {
1764         $response->headers->remove_header("Content-Length");
1765         $response->body('');
1766     }
1767
1768     $c->finalize_cookies;
1769
1770     $c->engine->finalize_headers( $c, @_ );
1771
1772     # Done
1773     $response->finalized_headers(1);
1774 }
1775
1776 =head2 $c->finalize_output
1777
1778 An alias for finalize_body.
1779
1780 =head2 $c->finalize_read
1781
1782 Finalizes the input after reading is complete.
1783
1784 =cut
1785
1786 sub finalize_read { my $c = shift; $c->engine->finalize_read( $c, @_ ) }
1787
1788 =head2 $c->finalize_uploads
1789
1790 Finalizes uploads. Cleans up any temporary files.
1791
1792 =cut
1793
1794 sub finalize_uploads { my $c = shift; $c->engine->finalize_uploads( $c, @_ ) }
1795
1796 =head2 $c->get_action( $action, $namespace )
1797
1798 Gets an action in a given namespace.
1799
1800 =cut
1801
1802 sub get_action { my $c = shift; $c->dispatcher->get_action(@_) }
1803
1804 =head2 $c->get_actions( $action, $namespace )
1805
1806 Gets all actions of a given name in a namespace and all parent
1807 namespaces.
1808
1809 =cut
1810
1811 sub get_actions { my $c = shift; $c->dispatcher->get_actions( $c, @_ ) }
1812
1813 =head2 $app->handle_request( @arguments )
1814
1815 Called to handle each HTTP request.
1816
1817 =cut
1818
1819 sub handle_request {
1820     my ( $class, @arguments ) = @_;
1821
1822     # Always expect worst case!
1823     my $status = -1;
1824     eval {
1825         if ($class->debug) {
1826             my $secs = time - $START || 1;
1827             my $av = sprintf '%.3f', $COUNT / $secs;
1828             my $time = localtime time;
1829             $class->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***");
1830         }
1831
1832         my $c = $class->prepare(@arguments);
1833         $c->dispatch;
1834         $status = $c->finalize;
1835     };
1836
1837     if ( my $error = $@ ) {
1838         chomp $error;
1839         $class->log->error(qq/Caught exception in engine "$error"/);
1840     }
1841
1842     $COUNT++;
1843
1844     if(my $coderef = $class->log->can('_flush')){
1845         $class->log->$coderef();
1846     }
1847     return $status;
1848 }
1849
1850 =head2 $c->prepare( @arguments )
1851
1852 Creates a Catalyst context from an engine-specific request (Apache, CGI,
1853 etc.).
1854
1855 =cut
1856
1857 sub prepare {
1858     my ( $class, @arguments ) = @_;
1859
1860     # XXX
1861     # After the app/ctxt split, this should become an attribute based on something passed
1862     # into the application.
1863     $class->context_class( ref $class || $class ) unless $class->context_class;
1864
1865     my $c = $class->context_class->new({});
1866
1867     # For on-demand data
1868     $c->request->_context($c);
1869     $c->response->_context($c);
1870
1871     #surely this is not the most efficient way to do things...
1872     $c->stats($class->stats_class->new)->enable($c->use_stats);
1873     if ( $c->debug || $c->config->{enable_catalyst_header} ) {
1874         $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
1875     }
1876
1877     #XXX reuse coderef from can
1878     # Allow engine to direct the prepare flow (for POE)
1879     if ( $c->engine->can('prepare') ) {
1880         $c->engine->prepare( $c, @arguments );
1881     }
1882     else {
1883         $c->prepare_request(@arguments);
1884         $c->prepare_connection;
1885         $c->prepare_query_parameters;
1886         $c->prepare_headers;
1887         $c->prepare_cookies;
1888         $c->prepare_path;
1889
1890         # Prepare the body for reading, either by prepare_body
1891         # or the user, if they are using $c->read
1892         $c->prepare_read;
1893
1894         # Parse the body unless the user wants it on-demand
1895         unless ( ref($c)->config->{parse_on_demand} ) {
1896             $c->prepare_body;
1897         }
1898     }
1899
1900     my $method  = $c->req->method  || '';
1901     my $path    = $c->req->path;
1902     $path       = '/' unless length $path;
1903     my $address = $c->req->address || '';
1904
1905     $c->log_request;
1906
1907     $c->prepare_action;
1908
1909     return $c;
1910 }
1911
1912 =head2 $c->prepare_action
1913
1914 Prepares action. See L<Catalyst::Dispatcher>.
1915
1916 =cut
1917
1918 sub prepare_action { my $c = shift; $c->dispatcher->prepare_action( $c, @_ ) }
1919
1920 =head2 $c->prepare_body
1921
1922 Prepares message body.
1923
1924 =cut
1925
1926 sub prepare_body {
1927     my $c = shift;
1928
1929     return if $c->request->_has_body;
1930
1931     # Initialize on-demand data
1932     $c->engine->prepare_body( $c, @_ );
1933     $c->prepare_parameters;
1934     $c->prepare_uploads;
1935 }
1936
1937 =head2 $c->prepare_body_chunk( $chunk )
1938
1939 Prepares a chunk of data before sending it to L<HTTP::Body>.
1940
1941 See L<Catalyst::Engine>.
1942
1943 =cut
1944
1945 sub prepare_body_chunk {
1946     my $c = shift;
1947     $c->engine->prepare_body_chunk( $c, @_ );
1948 }
1949
1950 =head2 $c->prepare_body_parameters
1951
1952 Prepares body parameters.
1953
1954 =cut
1955
1956 sub prepare_body_parameters {
1957     my $c = shift;
1958     $c->engine->prepare_body_parameters( $c, @_ );
1959 }
1960
1961 =head2 $c->prepare_connection
1962
1963 Prepares connection.
1964
1965 =cut
1966
1967 sub prepare_connection {
1968     my $c = shift;
1969     $c->engine->prepare_connection( $c, @_ );
1970 }
1971
1972 =head2 $c->prepare_cookies
1973
1974 Prepares cookies.
1975
1976 =cut
1977
1978 sub prepare_cookies { my $c = shift; $c->engine->prepare_cookies( $c, @_ ) }
1979
1980 =head2 $c->prepare_headers
1981
1982 Prepares headers.
1983
1984 =cut
1985
1986 sub prepare_headers { my $c = shift; $c->engine->prepare_headers( $c, @_ ) }
1987
1988 =head2 $c->prepare_parameters
1989
1990 Prepares parameters.
1991
1992 =cut
1993
1994 sub prepare_parameters {
1995     my $c = shift;
1996     $c->prepare_body_parameters;
1997     $c->engine->prepare_parameters( $c, @_ );
1998 }
1999
2000 =head2 $c->prepare_path
2001
2002 Prepares path and base.
2003
2004 =cut
2005
2006 sub prepare_path { my $c = shift; $c->engine->prepare_path( $c, @_ ) }
2007
2008 =head2 $c->prepare_query_parameters
2009
2010 Prepares query parameters.
2011
2012 =cut
2013
2014 sub prepare_query_parameters {
2015     my $c = shift;
2016
2017     $c->engine->prepare_query_parameters( $c, @_ );
2018 }
2019
2020 =head2 $c->log_request
2021
2022 Writes information about the request to the debug logs.  This includes:
2023
2024 =over 4
2025
2026 =item * Request method, path, and remote IP address
2027
2028 =item * Query keywords (see L<Catalyst::Request/query_keywords>)
2029
2030 =item * Request parameters
2031
2032 =item * File uploads
2033
2034 =back
2035
2036 =cut
2037
2038 sub log_request {
2039     my $c = shift;
2040
2041     return unless $c->debug;
2042
2043     my($dump) = grep {$_->[0] eq 'Request' } $c->dump_these;
2044     my $request = $dump->[1];
2045
2046     my ( $method, $path, $address ) = ( $request->method, $request->path, $request->address );
2047     $method ||= '';
2048     $path = '/' unless length $path;
2049     $address ||= '';
2050     $c->log->debug(qq/"$method" request for "$path" from "$address"/);
2051
2052     $c->log_request_headers($request->headers);
2053
2054     if ( my $keywords = $request->query_keywords ) {
2055         $c->log->debug("Query keywords are: $keywords");
2056     }
2057
2058     $c->log_request_parameters( query => $request->query_parameters, $request->_has_body ? (body => $request->body_parameters) : () );
2059
2060     $c->log_request_uploads($request);
2061 }
2062
2063 =head2 $c->log_response
2064
2065 Writes information about the response to the debug logs by calling
2066 C<< $c->log_response_status_line >> and C<< $c->log_response_headers >>.
2067
2068 =cut
2069
2070 sub log_response {
2071     my $c = shift;
2072
2073     return unless $c->debug;
2074
2075     my($dump) = grep {$_->[0] eq 'Response' } $c->dump_these;
2076     my $response = $dump->[1];
2077
2078     $c->log_response_status_line($response);
2079     $c->log_response_headers($response->headers);
2080 }
2081
2082 =head2 $c->log_response_status_line($response)
2083
2084 Writes one line of information about the response to the debug logs.  This includes:
2085
2086 =over 4
2087
2088 =item * Response status code
2089
2090 =item * Content-Type header (if present)
2091
2092 =item * Content-Length header (if present)
2093
2094 =back
2095
2096 =cut
2097
2098 sub log_response_status_line {
2099     my ($c, $response) = @_;
2100
2101     $c->log->debug(
2102         sprintf(
2103             'Response Code: %s; Content-Type: %s; Content-Length: %s',
2104             $response->status                            || 'unknown',
2105             $response->headers->header('Content-Type')   || 'unknown',
2106             $response->headers->header('Content-Length') || 'unknown'
2107         )
2108     );
2109 }
2110
2111 =head2 $c->log_response_headers($headers);
2112
2113 Hook method which can be wrapped by plugins to log the responseheaders.
2114 No-op in the default implementation.
2115
2116 =cut
2117
2118 sub log_response_headers {}
2119
2120 =head2 $c->log_request_parameters( query => {}, body => {} )
2121
2122 Logs request parameters to debug logs
2123
2124 =cut
2125
2126 sub log_request_parameters {
2127     my $c          = shift;
2128     my %all_params = @_;
2129
2130     return unless $c->debug;
2131
2132     my $column_width = Catalyst::Utils::term_width() - 44;
2133     foreach my $type (qw(query body)) {
2134         my $params = $all_params{$type};
2135         next if ! keys %$params;
2136         my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ $column_width, 'Value' ] );
2137         for my $key ( sort keys %$params ) {
2138             my $param = $params->{$key};
2139             my $value = defined($param) ? $param : '';
2140             $t->row( $key, ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
2141         }
2142         $c->log->debug( ucfirst($type) . " Parameters are:\n" . $t->draw );
2143     }
2144 }
2145
2146 =head2 $c->log_request_uploads
2147
2148 Logs file uploads included in the request to the debug logs.
2149 The parameter name, filename, file type, and file size are all included in
2150 the debug logs.
2151
2152 =cut
2153
2154 sub log_request_uploads {
2155     my $c = shift;
2156     my $request = shift;
2157     return unless $c->debug;
2158     my $uploads = $request->uploads;
2159     if ( keys %$uploads ) {
2160         my $t = Text::SimpleTable->new(
2161             [ 12, 'Parameter' ],
2162             [ 26, 'Filename' ],
2163             [ 18, 'Type' ],
2164             [ 9,  'Size' ]
2165         );
2166         for my $key ( sort keys %$uploads ) {
2167             my $upload = $uploads->{$key};
2168             for my $u ( ref $upload eq 'ARRAY' ? @{$upload} : ($upload) ) {
2169                 $t->row( $key, $u->filename, $u->type, $u->size );
2170             }
2171         }
2172         $c->log->debug( "File Uploads are:\n" . $t->draw );
2173     }
2174 }
2175
2176 =head2 $c->log_request_headers($headers);
2177
2178 Hook method which can be wrapped by plugins to log the request headers.
2179 No-op in the default implementation.
2180
2181 =cut
2182
2183 sub log_request_headers {}
2184
2185 =head2 $c->log_headers($type => $headers)
2186
2187 Logs L<HTTP::Headers> (either request or response) to the debug logs.
2188
2189 =cut
2190
2191 sub log_headers {
2192     my $c       = shift;
2193     my $type    = shift;
2194     my $headers = shift;    # an HTTP::Headers instance
2195
2196     return unless $c->debug;
2197
2198     my $column_width = Catalyst::Utils::term_width() - 28;
2199     my $t = Text::SimpleTable->new( [ 15, 'Header Name' ], [ $column_width, 'Value' ] );
2200     $headers->scan(
2201         sub {
2202             my ( $name, $value ) = @_;
2203             $t->row( $name, $value );
2204         }
2205     );
2206     $c->log->debug( ucfirst($type) . " Headers:\n" . $t->draw );
2207 }
2208
2209
2210 =head2 $c->prepare_read
2211
2212 Prepares the input for reading.
2213
2214 =cut
2215
2216 sub prepare_read { my $c = shift; $c->engine->prepare_read( $c, @_ ) }
2217
2218 =head2 $c->prepare_request
2219
2220 Prepares the engine request.
2221
2222 =cut
2223
2224 sub prepare_request { my $c = shift; $c->engine->prepare_request( $c, @_ ) }
2225
2226 =head2 $c->prepare_uploads
2227
2228 Prepares uploads.
2229
2230 =cut
2231
2232 sub prepare_uploads {
2233     my $c = shift;
2234
2235     $c->engine->prepare_uploads( $c, @_ );
2236 }
2237
2238 =head2 $c->prepare_write
2239
2240 Prepares the output for writing.
2241
2242 =cut
2243
2244 sub prepare_write { my $c = shift; $c->engine->prepare_write( $c, @_ ) }
2245
2246 =head2 $c->request_class
2247
2248 Returns or sets the request class. Defaults to L<Catalyst::Request>.
2249
2250 =head2 $c->response_class
2251
2252 Returns or sets the response class. Defaults to L<Catalyst::Response>.
2253
2254 =head2 $c->read( [$maxlength] )
2255
2256 Reads a chunk of data from the request body. This method is designed to
2257 be used in a while loop, reading C<$maxlength> bytes on every call.
2258 C<$maxlength> defaults to the size of the request if not specified.
2259
2260 You have to set C<< MyApp->config(parse_on_demand => 1) >> to use this
2261 directly.
2262
2263 Warning: If you use read(), Catalyst will not process the body,
2264 so you will not be able to access POST parameters or file uploads via
2265 $c->request.  You must handle all body parsing yourself.
2266
2267 =cut
2268
2269 sub read { my $c = shift; return $c->engine->read( $c, @_ ) }
2270
2271 =head2 $c->run
2272
2273 Starts the engine.
2274
2275 =cut
2276
2277 sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
2278
2279 =head2 $c->set_action( $action, $code, $namespace, $attrs )
2280
2281 Sets an action in a given namespace.
2282
2283 =cut
2284
2285 sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) }
2286
2287 =head2 $c->setup_actions($component)
2288
2289 Sets up actions for a component.
2290
2291 =cut
2292
2293 sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
2294
2295 =head2 $c->setup_config
2296
2297 =cut
2298
2299 sub setup_config {
2300     my $class = shift;
2301
2302     my %args = %{ $class->config || {} };
2303
2304     my @container_classes = ( "${class}::Container", 'Catalyst::IOC::Container');
2305     unshift @container_classes, delete $args{container_class} if exists $args{container_class};
2306
2307     my $container_class = Class::MOP::load_first_existing_class(@container_classes);
2308
2309     my $container = $container_class->new( %args, name => "$class" );
2310     $class->container($container);
2311
2312     my $config = $container->resolve(service => 'config');
2313     $class->config($config);
2314     $class->finalize_config; # back-compat
2315 }
2316
2317 =head2 $c->finalize_config
2318
2319 =cut
2320
2321 sub finalize_config { }
2322
2323 =head2 $c->setup_components
2324
2325 This method is called internally to set up the application's components.
2326
2327 It finds modules by calling the L<locate_components> method, expands them to
2328 package names with the L<expand_component_module> method, and then installs
2329 each component into the application.
2330
2331 The C<setup_components> config option is passed to both of the above methods.
2332
2333 Installation of each component is performed by the L<setup_component> method,
2334 below.
2335
2336 =cut
2337
2338 sub setup_components {
2339     my $class = shift;
2340
2341     my $config  = $class->config->{ setup_components };
2342
2343     my @comps = $class->locate_components($config);
2344     my %comps = map { $_ => 1 } @comps;
2345
2346     my $deprecatedcatalyst_component_names = grep { /::[CMV]::/ } @comps;
2347     $class->log->warn(qq{Your application is using the deprecated ::[MVC]:: type naming scheme.\n}.
2348         qq{Please switch your class names to ::Model::, ::View:: and ::Controller: as appropriate.\n}
2349     ) if $deprecatedcatalyst_component_names;
2350
2351     for my $component ( @comps ) {
2352
2353         # We pass ignore_loaded here so that overlay files for (e.g.)
2354         # Model::DBI::Schema sub-classes are loaded - if it's in @comps
2355         # we know M::P::O found a file on disk so this is safe
2356
2357         Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
2358     }
2359
2360     my $containers;
2361     $containers->{$_} = $class->container->get_sub_container($_) for qw(model view controller);
2362
2363     for my $component (@comps) {
2364         my $instance = $class->components->{ $component } = $class->setup_component($component);
2365         if ( my ($type, $name) = _get_component_type_name($component) ) {
2366             $containers->{$type}->add_service(Catalyst::IOC::BlockInjection->new( name => $name, block => sub { return $instance } ));
2367         }
2368         my @expanded_components = $instance->can('expand_modules')
2369             ? $instance->expand_modules( $component, $config )
2370             : $class->expand_component_module( $component, $config );
2371         for my $component (@expanded_components) {
2372             next if $comps{$component};
2373
2374             $deprecatedcatalyst_component_names = grep { /::[CMV]::/ } @expanded_components;
2375             $class->log->warn(qq{Your application is using the deprecated ::[MVC]:: type naming scheme.\n}.
2376                 qq{Please switch your class names to ::Model::, ::View:: and ::Controller: as appropriate.\n}
2377             ) if $deprecatedcatalyst_component_names;
2378
2379             if (my ($type, $name) = _get_component_type_name($component)) {
2380                 $containers->{$type}->add_service(Catalyst::IOC::BlockInjection->new( name => $name, block => sub { return $class->setup_component($component) } ));
2381             }
2382
2383             $class->components->{ $component } = $class->setup_component($component);
2384         }
2385     }
2386
2387     $containers->{model}->make_single_default;
2388     $containers->{view}->make_single_default;
2389 }
2390
2391 sub _get_component_type_name {
2392     my $component = shift;
2393     my @parts     = split /::/, $component;
2394
2395     while (my $type = shift @parts) {
2396         return ('controller', join '::', @parts)
2397             if $type =~ /^(c|controller)$/i;
2398
2399         return ('model', join '::', @parts)
2400             if $type =~ /^(m|model)$/i;
2401
2402         return ('view', join '::', @parts)
2403             if $type =~ /^(v|view)$/i;
2404     }
2405 }
2406
2407 =head2 $c->locate_components( $setup_component_config )
2408
2409 This method is meant to provide a list of component modules that should be
2410 setup for the application.  By default, it will use L<Module::Pluggable>.
2411
2412 Specify a C<setup_components> config option to pass additional options directly
2413 to L<Module::Pluggable>. To add additional search paths, specify a key named
2414 C<search_extra> as an array reference. Items in the array beginning with C<::>
2415 will have the application class name prepended to them.
2416
2417 =cut
2418
2419 sub locate_components {
2420     my $class  = shift;
2421     my $config = shift;
2422
2423     my @paths   = qw( ::Controller ::C ::Model ::M ::View ::V );
2424     my $extra   = delete $config->{ search_extra } || [];
2425
2426     push @paths, @$extra;
2427
2428     my $locator = Module::Pluggable::Object->new(
2429         search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
2430         %$config
2431     );
2432
2433     # XXX think about ditching this sort entirely
2434     my @comps = sort { length $a <=> length $b } $locator->plugins;
2435
2436     return @comps;
2437 }
2438
2439 =head2 $c->expand_component_module( $component, $setup_component_config )
2440
2441 Components found by C<locate_components> will be passed to this method, which
2442 is expected to return a list of component (package) names to be set up.
2443
2444 =cut
2445
2446 sub expand_component_module {
2447     my ($class, $module) = @_;
2448     return Devel::InnerPackage::list_packages( $module );
2449 }
2450
2451 =head2 $c->setup_component
2452
2453 =cut
2454
2455 sub setup_component {
2456     my( $class, $component ) = @_;
2457
2458     unless ( $component->can( 'COMPONENT' ) ) {
2459         return $component;
2460     }
2461
2462     my $suffix = Catalyst::Utils::class2classsuffix( $component );
2463     my $config = $class->config->{ $suffix } || {};
2464     # Stash catalyst_component_name in the config here, so that custom COMPONENT
2465     # methods also pass it. local to avoid pointlessly shitting in config
2466     # for the debug screen, as $component is already the key name.
2467     local $config->{catalyst_component_name} = $component;
2468
2469     my $instance = eval { $component->COMPONENT( $class, $config ); };
2470
2471     if ( my $error = $@ ) {
2472         chomp $error;
2473         Catalyst::Exception->throw(
2474             message => qq/Couldn't instantiate component "$component", "$error"/
2475         );
2476     }
2477     elsif (!blessed $instance) {
2478         my $metaclass = Moose::Util::find_meta($component);
2479         my $method_meta = $metaclass->find_method_by_name('COMPONENT');
2480         my $component_method_from = $method_meta->associated_metaclass->name;
2481         my $value = defined($instance) ? $instance : 'undef';
2482         Catalyst::Exception->throw(
2483             message =>
2484             qq/Couldn't instantiate component "$component", COMPONENT() method (from $component_method_from) didn't return an object-like value (value was $value)./
2485         );
2486     }
2487
2488     return $instance;
2489 }
2490
2491 =head2 $c->setup_dispatcher
2492
2493 Sets up dispatcher.
2494
2495 =cut
2496
2497 sub setup_dispatcher {
2498     my ( $class, $dispatcher ) = @_;
2499
2500     if ($dispatcher) {
2501         $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
2502     }
2503
2504     if ( my $env = Catalyst::Utils::env_value( $class, 'DISPATCHER' ) ) {
2505         $dispatcher = 'Catalyst::Dispatcher::' . $env;
2506     }
2507
2508     unless ($dispatcher) {
2509         $dispatcher = $class->dispatcher_class;
2510     }
2511
2512     Class::MOP::load_class($dispatcher);
2513
2514     # dispatcher instance
2515     $class->dispatcher( $dispatcher->new );
2516 }
2517
2518 =head2 $c->setup_engine
2519
2520 Sets up engine.
2521
2522 =cut
2523
2524 sub setup_engine {
2525     my ( $class, $engine ) = @_;
2526
2527     if ($engine) {
2528         $engine = 'Catalyst::Engine::' . $engine;
2529     }
2530
2531     if ( my $env = Catalyst::Utils::env_value( $class, 'ENGINE' ) ) {
2532         $engine = 'Catalyst::Engine::' . $env;
2533     }
2534
2535     if ( $ENV{MOD_PERL} ) {
2536         my $meta = Class::MOP::get_metaclass_by_name($class);
2537
2538         # create the apache method
2539         $meta->add_method('apache' => sub { shift->engine->apache });
2540
2541         my ( $software, $version ) =
2542           $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
2543
2544         $version =~ s/_//g;
2545         $version =~ s/(\.[^.]+)\./$1/g;
2546
2547         if ( $software eq 'mod_perl' ) {
2548
2549             if ( !$engine ) {
2550
2551                 if ( $version >= 1.99922 ) {
2552                     $engine = 'Catalyst::Engine::Apache2::MP20';
2553                 }
2554
2555                 elsif ( $version >= 1.9901 ) {
2556                     $engine = 'Catalyst::Engine::Apache2::MP19';
2557                 }
2558
2559                 elsif ( $version >= 1.24 ) {
2560                     $engine = 'Catalyst::Engine::Apache::MP13';
2561                 }
2562
2563                 else {
2564                     Catalyst::Exception->throw( message =>
2565                           qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
2566                 }
2567
2568             }
2569
2570             # install the correct mod_perl handler
2571             if ( $version >= 1.9901 ) {
2572                 *handler = sub  : method {
2573                     shift->handle_request(@_);
2574                 };
2575             }
2576             else {
2577                 *handler = sub ($$) { shift->handle_request(@_) };
2578             }
2579
2580         }
2581
2582         elsif ( $software eq 'Zeus-Perl' ) {
2583             $engine = 'Catalyst::Engine::Zeus';
2584         }
2585
2586         else {
2587             Catalyst::Exception->throw(
2588                 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/ );
2589         }
2590     }
2591
2592     unless ($engine) {
2593         $engine = $class->engine_class;
2594     }
2595
2596     Class::MOP::load_class($engine);
2597
2598     # check for old engines that are no longer compatible
2599     my $old_engine;
2600     if ( $engine->isa('Catalyst::Engine::Apache')
2601         && !Catalyst::Engine::Apache->VERSION )
2602     {
2603         $old_engine = 1;
2604     }
2605
2606     elsif ( $engine->isa('Catalyst::Engine::Server::Base')
2607         && Catalyst::Engine::Server->VERSION le '0.02' )
2608     {
2609         $old_engine = 1;
2610     }
2611
2612     elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
2613         && $engine->VERSION eq '0.01' )
2614     {
2615         $old_engine = 1;
2616     }
2617
2618     elsif ($engine->isa('Catalyst::Engine::Zeus')
2619         && $engine->VERSION eq '0.01' )
2620     {
2621         $old_engine = 1;
2622     }
2623
2624     if ($old_engine) {
2625         Catalyst::Exception->throw( message =>
2626               qq/Engine "$engine" is not supported by this version of Catalyst/
2627         );
2628     }
2629
2630     # engine instance
2631     $class->engine( $engine->new );
2632 }
2633
2634 =head2 $c->setup_home
2635
2636 Sets up the home directory.
2637
2638 =cut
2639
2640 sub setup_home {
2641     my ( $class, $home ) = @_;
2642
2643     if ( my $env = Catalyst::Utils::env_value( $class, 'HOME' ) ) {
2644         $home = $env;
2645     }
2646
2647     $home ||= Catalyst::Utils::home($class);
2648
2649     if ($home) {
2650         #I remember recently being scolded for assigning config values like this
2651         $class->config->{home} ||= $home;
2652         $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
2653     }
2654 }
2655
2656 =head2 $c->setup_log
2657
2658 Sets up log by instantiating a L<Catalyst::Log|Catalyst::Log> object and
2659 passing it to C<log()>. Pass in a comma-delimited list of levels to set the
2660 log to.
2661
2662 This method also installs a C<debug> method that returns a true value into the
2663 catalyst subclass if the "debug" level is passed in the comma-delimited list,
2664 or if the C<$CATALYST_DEBUG> environment variable is set to a true value.
2665
2666 Note that if the log has already been setup, by either a previous call to
2667 C<setup_log> or by a call such as C<< __PACKAGE__->log( MyLogger->new ) >>,
2668 that this method won't actually set up the log object.
2669
2670 =cut
2671
2672 sub setup_log {
2673     my ( $class, $levels ) = @_;
2674
2675     $levels ||= '';
2676     $levels =~ s/^\s+//;
2677     $levels =~ s/\s+$//;
2678     my %levels = map { $_ => 1 } split /\s*,\s*/, $levels;
2679
2680     my $env_debug = Catalyst::Utils::env_value( $class, 'DEBUG' );
2681     if ( defined $env_debug ) {
2682         $levels{debug} = 1 if $env_debug; # Ugly!
2683         delete($levels{debug}) unless $env_debug;
2684     }
2685
2686     unless ( $class->log ) {
2687         $class->log( Catalyst::Log->new(keys %levels) );
2688     }
2689
2690     if ( $levels{debug} ) {
2691         Class::MOP::get_metaclass_by_name($class)->add_method('debug' => sub { 1 });
2692         $class->log->debug('Debug messages enabled');
2693     }
2694 }
2695
2696 =head2 $c->setup_plugins
2697
2698 Sets up plugins.
2699
2700 =cut
2701
2702 =head2 $c->setup_stats
2703
2704 Sets up timing statistics class.
2705
2706 =cut
2707
2708 sub setup_stats {
2709     my ( $class, $stats ) = @_;
2710
2711     Catalyst::Utils::ensure_class_loaded($class->stats_class);
2712
2713     my $env = Catalyst::Utils::env_value( $class, 'STATS' );
2714     if ( defined($env) ? $env : ($stats || $class->debug ) ) {
2715         Class::MOP::get_metaclass_by_name($class)->add_method('use_stats' => sub { 1 });
2716         $class->log->debug('Statistics enabled');
2717     }
2718 }
2719
2720
2721 =head2 $c->registered_plugins
2722
2723 Returns a sorted list of the plugins which have either been stated in the
2724 import list or which have been added via C<< MyApp->plugin(@args); >>.
2725
2726 If passed a given plugin name, it will report a boolean value indicating
2727 whether or not that plugin is loaded.  A fully qualified name is required if
2728 the plugin name does not begin with C<Catalyst::Plugin::>.
2729
2730  if ($c->registered_plugins('Some::Plugin')) {
2731      ...
2732  }
2733
2734 =cut
2735
2736 {
2737
2738     sub registered_plugins {
2739         my $proto = shift;
2740         return sort keys %{ $proto->_plugins } unless @_;
2741         my $plugin = shift;
2742         return 1 if exists $proto->_plugins->{$plugin};
2743         return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"};
2744     }
2745
2746     sub _register_plugin {
2747         my ( $proto, $plugin, $instant ) = @_;
2748         my $class = ref $proto || $proto;
2749
2750         Class::MOP::load_class( $plugin );
2751         $class->log->warn( "$plugin inherits from 'Catalyst::Component' - this is deprecated and will not work in 5.81" )
2752             if $plugin->isa( 'Catalyst::Component' );
2753         $proto->_plugins->{$plugin} = 1;
2754         unless ($instant) {
2755             my $meta = Class::MOP::get_metaclass_by_name($class);
2756             $meta->superclasses($plugin, $meta->superclasses);
2757         }
2758         return $class;
2759     }
2760
2761     sub setup_plugins {
2762         my ( $class, $plugins ) = @_;
2763
2764         $class->_plugins( {} ) unless $class->_plugins;
2765         $plugins = Data::OptList::mkopt($plugins || []);
2766
2767         my @plugins = map {
2768             [ Catalyst::Utils::resolve_namespace(
2769                   $class . '::Plugin',
2770                   'Catalyst::Plugin', $_->[0]
2771               ),
2772               $_->[1],
2773             ]
2774          } @{ $plugins };
2775
2776         for my $plugin ( reverse @plugins ) {
2777             Class::MOP::load_class($plugin->[0], $plugin->[1]);
2778             my $meta = find_meta($plugin->[0]);
2779             next if $meta && $meta->isa('Moose::Meta::Role');
2780
2781             $class->_register_plugin($plugin->[0]);
2782         }
2783
2784         my @roles =
2785             map  { $_->[0]->name, $_->[1] }
2786             grep { blessed($_->[0]) && $_->[0]->isa('Moose::Meta::Role') }
2787             map  { [find_meta($_->[0]), $_->[1]] }
2788             @plugins;
2789
2790         Moose::Util::apply_all_roles(
2791             $class => @roles
2792         ) if @roles;
2793     }
2794 }
2795
2796 =head2 $c->stack
2797
2798 Returns an arrayref of the internal execution stack (actions that are
2799 currently executing).
2800
2801 =head2 $c->stats
2802
2803 Returns the current timing statistics object. By default Catalyst uses
2804 L<Catalyst::Stats|Catalyst::Stats>, but can be set otherwise with
2805 L<< stats_class|/"$c->stats_class" >>.
2806
2807 Even if L<< -Stats|/"-Stats" >> is not enabled, the stats object is still
2808 available. By enabling it with C< $c->stats->enabled(1) >, it can be used to
2809 profile explicitly, although MyApp.pm still won't profile nor output anything
2810 by itself.
2811
2812 =head2 $c->stats_class
2813
2814 Returns or sets the stats (timing statistics) class. L<Catalyst::Stats|Catalyst::Stats> is used by default.
2815
2816 =head2 $c->use_stats
2817
2818 Returns 1 when L<< stats collection|/"-Stats" >> is enabled.
2819
2820 Note that this is a static method, not an accessor and should be overridden
2821 by declaring C<sub use_stats { 1 }> in your MyApp.pm, not by calling C<< $c->use_stats(1) >>.
2822
2823 =cut
2824
2825 sub use_stats { 0 }
2826
2827
2828 =head2 $c->write( $data )
2829
2830 Writes $data to the output stream. When using this method directly, you
2831 will need to manually set the C<Content-Length> header to the length of
2832 your output data, if known.
2833
2834 =cut
2835
2836 sub write {
2837     my $c = shift;
2838
2839     # Finalize headers if someone manually writes output
2840     $c->finalize_headers;
2841
2842     return $c->engine->write( $c, @_ );
2843 }
2844
2845 =head2 version
2846
2847 Returns the Catalyst version number. Mostly useful for "powered by"
2848 messages in template systems.
2849
2850 =cut
2851
2852 sub version { return $Catalyst::VERSION }
2853
2854 =head1 CONFIGURATION
2855
2856 There are a number of 'base' config variables which can be set:
2857
2858 =over
2859
2860 =item *
2861
2862 C<default_model> - The default model picked if you say C<< $c->model >>. See L<< /$c->model($name) >>.
2863
2864 =item *
2865
2866 C<default_view> - The default view to be rendered or returned when C<< $c->view >> is called. See L<< /$c->view($name) >>.
2867
2868 =item *
2869
2870 C<home> - The application home directory. In an uninstalled application,
2871 this is the top level application directory. In an installed application,
2872 this will be the directory containing C<< MyApp.pm >>.
2873
2874 =item *
2875
2876 C<ignore_frontend_proxy> - See L</PROXY SUPPORT>
2877
2878 =item *
2879
2880 C<name> - The name of the application in debug messages and the debug and
2881 welcome screens
2882
2883 =item *
2884
2885 C<parse_on_demand> - The request body (for example file uploads) will not be parsed
2886 until it is accessed. This allows you to (for example) check authentication (and reject
2887 the upload) before actually recieving all the data. See L</ON-DEMAND PARSER>
2888
2889 =item *
2890
2891 C<root> - The root directory for templates. Usually this is just a
2892 subdirectory of the home directory, but you can set it to change the
2893 templates to a different directory.
2894
2895 =item *
2896
2897 C<search_extra> - Array reference passed to Module::Pluggable to for additional
2898 namespaces from which components will be loaded (and constructed and stored in
2899 C<< $c->components >>).
2900
2901 =item *
2902
2903 C<show_internal_actions> - If true, causes internal actions such as C<< _DISPATCH >>
2904 to be shown in hit debug tables in the test server.
2905
2906 =item *
2907
2908 C<use_request_uri_for_path> - Controlls if the C<REQUEST_URI> or C<PATH_INFO> environment
2909 variable should be used for determining the request path. See L<Catalyst::Engine::CGI/PATH DECODING>
2910 for more information.
2911
2912 =item *
2913
2914 C<using_frontend_proxy> - See L</PROXY SUPPORT>.
2915
2916 =back
2917
2918 =head1 INTERNAL ACTIONS
2919
2920 Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
2921 C<_ACTION>, and C<_END>. These are by default not shown in the private
2922 action table, but you can make them visible with a config parameter.
2923
2924     MyApp->config(show_internal_actions => 1);
2925
2926 =head1 ON-DEMAND PARSER
2927
2928 The request body is usually parsed at the beginning of a request,
2929 but if you want to handle input yourself, you can enable on-demand
2930 parsing with a config parameter.
2931
2932     MyApp->config(parse_on_demand => 1);
2933
2934 =head1 PROXY SUPPORT
2935
2936 Many production servers operate using the common double-server approach,
2937 with a lightweight frontend web server passing requests to a larger
2938 backend server. An application running on the backend server must deal
2939 with two problems: the remote user always appears to be C<127.0.0.1> and
2940 the server's hostname will appear to be C<localhost> regardless of the
2941 virtual host that the user connected through.
2942
2943 Catalyst will automatically detect this situation when you are running
2944 the frontend and backend servers on the same machine. The following
2945 changes are made to the request.
2946
2947     $c->req->address is set to the user's real IP address, as read from
2948     the HTTP X-Forwarded-For header.
2949
2950     The host value for $c->req->base and $c->req->uri is set to the real
2951     host, as read from the HTTP X-Forwarded-Host header.
2952
2953 Additionally, you may be running your backend application on an insecure
2954 connection (port 80) while your frontend proxy is running under SSL.  If there
2955 is a discrepancy in the ports, use the HTTP header C<X-Forwarded-Port> to
2956 tell Catalyst what port the frontend listens on.  This will allow all URIs to
2957 be created properly.
2958
2959 In the case of passing in:
2960
2961     X-Forwarded-Port: 443
2962
2963 All calls to C<uri_for> will result in an https link, as is expected.
2964
2965 Obviously, your web server must support these headers for this to work.
2966
2967 In a more complex server farm environment where you may have your
2968 frontend proxy server(s) on different machines, you will need to set a
2969 configuration option to tell Catalyst to read the proxied data from the
2970 headers.
2971
2972     MyApp->config(using_frontend_proxy => 1);
2973
2974 If you do not wish to use the proxy support at all, you may set:
2975
2976     MyApp->config(ignore_frontend_proxy => 1);
2977
2978 =head1 THREAD SAFETY
2979
2980 Catalyst has been tested under Apache 2's threading C<mpm_worker>,
2981 C<mpm_winnt>, and the standalone forking HTTP server on Windows. We
2982 believe the Catalyst core to be thread-safe.
2983
2984 If you plan to operate in a threaded environment, remember that all other
2985 modules you are using must also be thread-safe. Some modules, most notably
2986 L<DBD::SQLite>, are not thread-safe.
2987
2988 =head1 SUPPORT
2989
2990 IRC:
2991
2992     Join #catalyst on irc.perl.org.
2993
2994 Mailing Lists:
2995
2996     http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
2997     http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
2998
2999 Web:
3000
3001     http://catalyst.perl.org
3002
3003 Wiki:
3004
3005     http://dev.catalyst.perl.org
3006
3007 =head1 SEE ALSO
3008
3009 =head2 L<Task::Catalyst> - All you need to start with Catalyst
3010
3011 =head2 L<Catalyst::Manual> - The Catalyst Manual
3012
3013 =head2 L<Catalyst::Component>, L<Catalyst::Controller> - Base classes for components
3014
3015 =head2 L<Catalyst::Engine> - Core engine
3016
3017 =head2 L<Catalyst::Log> - Log class.
3018
3019 =head2 L<Catalyst::Request> - Request object
3020
3021 =head2 L<Catalyst::Response> - Response object
3022
3023 =head2 L<Catalyst::Test> - The test suite.
3024
3025 =head1 PROJECT FOUNDER
3026
3027 sri: Sebastian Riedel <sri@cpan.org>
3028
3029 =head1 CONTRIBUTORS
3030
3031 abw: Andy Wardley
3032
3033 acme: Leon Brocard <leon@astray.com>
3034
3035 abraxxa: Alexander Hartmaier <abraxxa@cpan.org>
3036
3037 Andrew Bramble
3038
3039 Andrew Ford E<lt>A.Ford@ford-mason.co.ukE<gt>
3040
3041 Andrew Ruthven
3042
3043 André Walker
3044
3045 andyg: Andy Grundman <andy@hybridized.org>
3046
3047 audreyt: Audrey Tang
3048
3049 bricas: Brian Cassidy <bricas@cpan.org>
3050
3051 Caelum: Rafael Kitover <rkitover@io.com>
3052
3053 chansen: Christian Hansen
3054
3055 chicks: Christopher Hicks
3056
3057 Chisel Wright C<pause@herlpacker.co.uk>
3058
3059 Danijel Milicevic C<me@danijel.de>
3060
3061 David Kamholz E<lt>dkamholz@cpan.orgE<gt>
3062
3063 David Naughton, C<naughton@umn.edu>
3064
3065 David E. Wheeler
3066
3067 dhoss: Devin Austin <dhoss@cpan.org>
3068
3069 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
3070
3071 Drew Taylor
3072
3073 dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
3074
3075 esskar: Sascha Kiefer
3076
3077 fireartist: Carl Franks <cfranks@cpan.org>
3078
3079 frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
3080
3081 gabb: Danijel Milicevic
3082
3083 Gary Ashton Jones
3084
3085 Gavin Henry C<ghenry@perl.me.uk>
3086
3087 Geoff Richards
3088
3089 groditi: Guillermo Roditi <groditi@gmail.com>
3090
3091 hobbs: Andrew Rodland <andrew@cleverdomain.org>
3092
3093 ilmari: Dagfinn Ilmari MannsÃ¥ker <ilmari@ilmari.org>
3094
3095 jcamacho: Juan Camacho
3096
3097 jester: Jesse Sheidlower C<jester@panix.com>
3098
3099 jhannah: Jay Hannah <jay@jays.net>
3100
3101 Jody Belka
3102
3103 Johan Lindstrom
3104
3105 jon: Jon Schutz <jjschutz@cpan.org>
3106
3107 Jonathan Rockway C<< <jrockway@cpan.org> >>
3108
3109 Kieren Diment C<kd@totaldatasolution.com>
3110
3111 konobi: Scott McWhirter <konobi@cpan.org>
3112
3113 marcus: Marcus Ramberg <mramberg@cpan.org>
3114
3115 miyagawa: Tatsuhiko Miyagawa <miyagawa@bulknews.net>
3116
3117 mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
3118
3119 mugwump: Sam Vilain
3120
3121 naughton: David Naughton
3122
3123 ningu: David Kamholz <dkamholz@cpan.org>
3124
3125 nothingmuch: Yuval Kogman <nothingmuch@woobling.org>
3126
3127 numa: Dan Sully <daniel@cpan.org>
3128
3129 obra: Jesse Vincent
3130
3131 Octavian Rasnita
3132
3133 omega: Andreas Marienborg
3134
3135 Oleg Kostyuk <cub.uanic@gmail.com>
3136
3137 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
3138
3139 rafl: Florian Ragwitz <rafl@debian.org>
3140
3141 random: Roland Lammel <lammel@cpan.org>
3142
3143 Robert Sedlacek C<< <rs@474.at> >>
3144
3145 SpiceMan: Marcel Montes
3146
3147 sky: Arthur Bergman
3148
3149 szbalint: Balint Szilakszi <szbalint@cpan.org>
3150
3151 t0m: Tomas Doran <bobtfish@bobtfish.net>
3152
3153 Ulf Edvinsson
3154
3155 Viljo Marrandi C<vilts@yahoo.com>
3156
3157 Will Hawes C<info@whawes.co.uk>
3158
3159 willert: Sebastian Willert <willert@cpan.org>
3160
3161 wreis: Wallace Reis <wallace@reis.org.br>
3162
3163 Yuval Kogman, C<nothingmuch@woobling.org>
3164
3165 rainboxx: Matthias Dietrich, C<perl@rainboxx.de>
3166
3167 dd070: Dhaval Dhanani <dhaval070@gmail.com>
3168
3169 =head1 COPYRIGHT
3170
3171 Copyright (c) 2005, the above named PROJECT FOUNDER and CONTRIBUTORS.
3172
3173 =head1 LICENSE
3174
3175 This library is free software. You can redistribute it and/or modify it under
3176 the same terms as Perl itself.
3177
3178 =cut
3179
3180 no Moose;
3181
3182 __PACKAGE__->meta->make_immutable;
3183
3184 1;