Fix missing =back in pod
[catagits/Catalyst-Runtime.git] / lib / Catalyst.pm
CommitLineData
fc7ec1d9 1package Catalyst;
2
a7caa492 3use Moose;
4extends 'Catalyst::Component';
fbcc39ad 5use bytes;
a2f2cde9 6use Catalyst::Exception;
fc7ec1d9 7use Catalyst::Log;
fbcc39ad 8use Catalyst::Request;
9use Catalyst::Request::Upload;
10use Catalyst::Response;
812a28c9 11use Catalyst::Utils;
31375184 12use Catalyst::Controller;
364d7324 13use Devel::InnerPackage ();
8f62c91a 14use File::stat;
c50f595c 15use Module::Pluggable::Object ();
c50f595c 16use Text::SimpleTable ();
17use Path::Class::Dir ();
18use Path::Class::File ();
fbcc39ad 19use Time::HiRes qw/gettimeofday tv_interval/;
c50f595c 20use URI ();
933ba403 21use URI::http;
22use URI::https;
6a4a7002 23use Scalar::Util qw/weaken blessed/;
5513038d 24use Tree::Simple qw/use_weak_refs/;
25use Tree::Simple::Visitor::FindByUID;
261c571e 26use attributes;
5789a3d8 27use utf8;
c45c5d37 28use Carp qw/croak carp/;
fc7ec1d9 29
f63c03e4 30BEGIN { require 5.008001; }
31
6680c772 32has stack => (is => 'rw', default => sub { [] });
33has stash => (is => 'rw', default => sub { {} });
34has state => (is => 'rw', default => 0);
b6d4ee6e 35has stats => (is => 'rw');
36has action => (is => 'rw');
6680c772 37has counter => (is => 'rw', default => sub { {} });
38has request => (is => 'rw', default => sub { $_[0]->request_class->new({}) }, required => 1, lazy => 1);
39has response => (is => 'rw', default => sub { $_[0]->response_class->new({}) }, required => 1, lazy => 1);
e63bdf38 40has namespace => (is => 'rw');
41
8767c5a3 42sub depth { scalar @{ shift->stack || [] }; }
0fc2d522 43sub comp { shift->component(@_) }
6680c772 44
45sub req {
46 # carp "the use of req() is deprecated in favour of request()";
47 my $self = shift; return $self->request(@_);
48}
49sub res {
50 # carp "the use of res() is deprecated in favour of response()";
51 my $self = shift; return $self->response(@_);
52}
fbcc39ad 53
54# For backwards compatibility
0fc2d522 55sub finalize_output { shift->finalize_body(@_) };
fbcc39ad 56
57# For statistics
58our $COUNT = 1;
59our $START = time;
60our $RECURSION = 1000;
61our $DETACH = "catalyst_detach\n";
55424863 62our $GO = "catalyst_go\n";
fbcc39ad 63
b6d4ee6e 64#I imagine that very few of these really need to be class variables. if any.
65#maybe we should just make them attributes with a default?
fbcc39ad 66__PACKAGE__->mk_classdata($_)
3cec521a 67 for qw/components arguments dispatcher engine log dispatcher_class
ac5c933b 68 engine_class context_class request_class response_class stats_class
dc5f035e 69 setup_finished/;
cb0354c6 70
3cec521a 71__PACKAGE__->dispatcher_class('Catalyst::Dispatcher');
72__PACKAGE__->engine_class('Catalyst::Engine::CGI');
73__PACKAGE__->request_class('Catalyst::Request');
74__PACKAGE__->response_class('Catalyst::Response');
dc5f035e 75__PACKAGE__->stats_class('Catalyst::Stats');
fbcc39ad 76
6415bb4d 77# Remember to update this in Catalyst::Runtime as well!
78
47a6ff61 79our $VERSION = '5.8000_02';
189e2a51 80
fbcc39ad 81sub import {
82 my ( $class, @arguments ) = @_;
83
84 # We have to limit $class to Catalyst to avoid pushing Catalyst upon every
85 # callers @ISA.
86 return unless $class eq 'Catalyst';
87
84ff88cf 88 my $caller = caller();
89 return if $caller eq 'main';
90 my $meta = Moose::Meta::Class->initialize($caller);
91 #Moose->import({ into => $caller }); #do we want to do this?
fbcc39ad 92
93 unless ( $caller->isa('Catalyst') ) {
84ff88cf 94 my @superclasses = ($meta->superclasses, $class, 'Catalyst::Controller');
95 $meta->superclasses(@superclasses);
96 }
97 unless( $meta->has_method('meta') ){
98 $meta->add_method(meta => sub { Moose::Meta::Class->initialize("${caller}") } );
fbcc39ad 99 }
100
101 $caller->arguments( [@arguments] );
102 $caller->setup_home;
103}
fc7ec1d9 104
105=head1 NAME
106
107Catalyst - The Elegant MVC Web Application Framework
108
109=head1 SYNOPSIS
110
e7ad3b81 111See the L<Catalyst::Manual> distribution for comprehensive
112documentation and tutorials.
113
86418559 114 # Install Catalyst::Devel for helpers and other development tools
b4b01a8a 115 # use the helper to create a new application
91864987 116 catalyst.pl MyApp
fc7ec1d9 117
118 # add models, views, controllers
2f381252 119 script/myapp_create.pl model MyDatabase DBIC::Schema create=static dbi:SQLite:/path/to/db
cc95842f 120 script/myapp_create.pl view MyTemplate TT
0ef52a96 121 script/myapp_create.pl controller Search
fc7ec1d9 122
e7f1cf73 123 # built in testserver -- use -r to restart automatically on changes
cc95842f 124 # --help to see all available options
ae4e40a7 125 script/myapp_server.pl
fc7ec1d9 126
0ef52a96 127 # command line testing interface
ae4e40a7 128 script/myapp_test.pl /yada
fc7ec1d9 129
b4b01a8a 130 ### in lib/MyApp.pm
0ef52a96 131 use Catalyst qw/-Debug/; # include plugins here as well
ac5c933b 132
85d9fce6 133 ### In lib/MyApp/Controller/Root.pm (autocreated)
0ef52a96 134 sub foo : Global { # called for /foo, /foo/1, /foo/1/2, etc.
ae1e6b59 135 my ( $self, $c, @args ) = @_; # args are qw/1 2/ for /foo/1/2
136 $c->stash->{template} = 'foo.tt'; # set the template
0ef52a96 137 # lookup something from db -- stash vars are passed to TT
ac5c933b 138 $c->stash->{data} =
b4b01a8a 139 $c->model('Database::Foo')->search( { country => $args[0] } );
0ef52a96 140 if ( $c->req->params->{bar} ) { # access GET or POST parameters
141 $c->forward( 'bar' ); # process another action
ac5c933b 142 # do something else after forward returns
0ef52a96 143 }
144 }
ac5c933b 145
ae1e6b59 146 # The foo.tt TT template can use the stash data from the database
0ef52a96 147 [% WHILE (item = data.next) %]
148 [% item.foo %]
149 [% END %]
ac5c933b 150
0ef52a96 151 # called for /bar/of/soap, /bar/of/soap/10, etc.
152 sub bar : Path('/bar/of/soap') { ... }
fc7ec1d9 153
ae1e6b59 154 # called for all actions, from the top-most controller downwards
ac5c933b 155 sub auto : Private {
0ef52a96 156 my ( $self, $c ) = @_;
b4b01a8a 157 if ( !$c->user_exists ) { # Catalyst::Plugin::Authentication
0ef52a96 158 $c->res->redirect( '/login' ); # require login
159 return 0; # abort request and go immediately to end()
160 }
ae1e6b59 161 return 1; # success; carry on to next action
0ef52a96 162 }
ac5c933b 163
ae1e6b59 164 # called after all actions are finished
ac5c933b 165 sub end : Private {
5a8ed4fe 166 my ( $self, $c ) = @_;
0ef52a96 167 if ( scalar @{ $c->error } ) { ... } # handle errors
168 return if $c->res->body; # already have a response
169 $c->forward( 'MyApp::View::TT' ); # render template
5a8ed4fe 170 }
171
0ef52a96 172 ### in MyApp/Controller/Foo.pm
173 # called for /foo/bar
174 sub bar : Local { ... }
ac5c933b 175
5400c668 176 # called for /blargle
177 sub blargle : Global { ... }
ac5c933b 178
5400c668 179 # an index action matches /foo, but not /foo/1, etc.
180 sub index : Private { ... }
ac5c933b 181
0ef52a96 182 ### in MyApp/Controller/Foo/Bar.pm
183 # called for /foo/bar/baz
184 sub baz : Local { ... }
ac5c933b 185
b4b01a8a 186 # first Root auto is called, then Foo auto, then this
0ef52a96 187 sub auto : Private { ... }
ac5c933b 188
0ef52a96 189 # powerful regular expression paths are also possible
190 sub details : Regex('^product/(\w+)/details$') {
5a8ed4fe 191 my ( $self, $c ) = @_;
0ef52a96 192 # extract the (\w+) from the URI
2982e768 193 my $product = $c->req->captures->[0];
5a8ed4fe 194 }
fc7ec1d9 195
0ef52a96 196See L<Catalyst::Manual::Intro> for additional information.
3803e98f 197
fc7ec1d9 198=head1 DESCRIPTION
199
86418559 200Catalyst is a modern framework for making web applications without the
201pain usually associated with this process. This document is a reference
202to the main Catalyst application. If you are a new user, we suggest you
203start with L<Catalyst::Manual::Tutorial> or L<Catalyst::Manual::Intro>.
fc7ec1d9 204
205See L<Catalyst::Manual> for more documentation.
206
ae1e6b59 207Catalyst plugins can be loaded by naming them as arguments to the "use
208Catalyst" statement. Omit the C<Catalyst::Plugin::> prefix from the
209plugin name, i.e., C<Catalyst::Plugin::My::Module> becomes
210C<My::Module>.
fc7ec1d9 211
0ef52a96 212 use Catalyst qw/My::Module/;
fc7ec1d9 213
836e1134 214If your plugin starts with a name other than C<Catalyst::Plugin::>, you can
215fully qualify the name by using a unary plus:
216
217 use Catalyst qw/
218 My::Module
219 +Fully::Qualified::Plugin::Name
220 /;
221
ae1e6b59 222Special flags like C<-Debug> and C<-Engine> can also be specified as
223arguments when Catalyst is loaded:
fc7ec1d9 224
225 use Catalyst qw/-Debug My::Module/;
226
ae1e6b59 227The position of plugins and flags in the chain is important, because
86418559 228they are loaded in the order in which they appear.
fc7ec1d9 229
23f9d934 230The following flags are supported:
231
b5ecfcf0 232=head2 -Debug
23f9d934 233
f8ad6ea5 234Enables debug output. You can also force this setting from the system
86418559 235environment with CATALYST_DEBUG or <MYAPP>_DEBUG. The environment
236settings override the application, with <MYAPP>_DEBUG having the highest
237priority.
fc7ec1d9 238
b5ecfcf0 239=head2 -Engine
fc7ec1d9 240
ae1e6b59 241Forces Catalyst to use a specific engine. Omit the
242C<Catalyst::Engine::> prefix of the engine name, i.e.:
fc7ec1d9 243
0ef52a96 244 use Catalyst qw/-Engine=CGI/;
fc7ec1d9 245
b5ecfcf0 246=head2 -Home
fbcc39ad 247
ae1e6b59 248Forces Catalyst to use a specific home directory, e.g.:
249
86418559 250 use Catalyst qw[-Home=/usr/mst];
fbcc39ad 251
cc95842f 252This can also be done in the shell environment by setting either the
253C<CATALYST_HOME> environment variable or C<MYAPP_HOME>; where C<MYAPP>
254is replaced with the uppercased name of your application, any "::" in
255the name will be replaced with underscores, e.g. MyApp::Web should use
256MYAPP_WEB_HOME. If both variables are set, the MYAPP_HOME one will be used.
257
b5ecfcf0 258=head2 -Log
fbcc39ad 259
0ef52a96 260Specifies log level.
fbcc39ad 261
dc5f035e 262=head2 -Stats
263
264Enables statistics collection and reporting. You can also force this setting
265from the system environment with CATALYST_STATS or <MYAPP>_STATS. The
266environment settings override the application, with <MYAPP>_STATS having the
267highest priority.
268
ac5c933b 269e.g.
dc5f035e 270
271 use Catalyst qw/-Stats=1/
272
23f9d934 273=head1 METHODS
274
f7b672ef 275=head2 INFORMATION ABOUT THE CURRENT REQUEST
0ef52a96 276
b5ecfcf0 277=head2 $c->action
66e28e3f 278
ae1e6b59 279Returns a L<Catalyst::Action> object for the current action, which
280stringifies to the action name. See L<Catalyst::Action>.
0ef52a96 281
b5ecfcf0 282=head2 $c->namespace
0ef52a96 283
86418559 284Returns the namespace of the current action, i.e., the URI prefix
ae1e6b59 285corresponding to the controller of the current action. For example:
286
287 # in Controller::Foo::Bar
288 $c->namespace; # returns 'foo/bar';
0ef52a96 289
b5ecfcf0 290=head2 $c->request
0ef52a96 291
b5ecfcf0 292=head2 $c->req
0ef52a96 293
86418559 294Returns the current L<Catalyst::Request> object, giving access to
295information about the current client request (including parameters,
296cookies, HTTP headers, etc.). See L<Catalyst::Request>.
0ef52a96 297
b4b01a8a 298=head2 REQUEST FLOW HANDLING
0ef52a96 299
b5ecfcf0 300=head2 $c->forward( $action [, \@arguments ] )
0ef52a96 301
b5ecfcf0 302=head2 $c->forward( $class, $method, [, \@arguments ] )
0ef52a96 303
86418559 304Forwards processing to another action, by its private name. If you give a
b4b01a8a 305class name but no method, C<process()> is called. You may also optionally
306pass arguments in an arrayref. The action will receive the arguments in
cc95842f 307C<@_> and C<< $c->req->args >>. Upon returning from the function,
308C<< $c->req->args >> will be restored to the previous values.
0ef52a96 309
3b984c64 310Any data C<return>ed from the action forwarded to, will be returned by the
d759db1e 311call to forward.
3b984c64 312
313 my $foodata = $c->forward('/foo');
0ef52a96 314 $c->forward('index');
e112461a 315 $c->forward(qw/MyApp::Model::DBIC::Foo do_stuff/);
0ef52a96 316 $c->forward('MyApp::View::TT');
317
86418559 318Note that forward implies an C<<eval { }>> around the call (actually
319C<execute> does), thus de-fatalizing all 'dies' within the called
320action. If you want C<die> to propagate you need to do something like:
f3e6a8c0 321
322 $c->forward('foo');
323 die $c->error if $c->error;
324
86418559 325Or make sure to always return true values from your actions and write
326your code like this:
f3e6a8c0 327
328 $c->forward('foo') || return;
329
0ef52a96 330=cut
331
6680c772 332sub forward { my $c = shift; no warnings 'recursion'; $c->dispatcher->forward( $c, @_ ) }
0ef52a96 333
b5ecfcf0 334=head2 $c->detach( $action [, \@arguments ] )
0ef52a96 335
b5ecfcf0 336=head2 $c->detach( $class, $method, [, \@arguments ] )
0ef52a96 337
264bac8c 338=head2 $c->detach()
339
ac5c933b 340The same as C<forward>, but doesn't return to the previous action when
341processing is finished.
0ef52a96 342
264bac8c 343When called with no arguments it escapes the processing chain entirely.
344
0ef52a96 345=cut
346
347sub detach { my $c = shift; $c->dispatcher->detach( $c, @_ ) }
348
ae0e35ee 349=head2 $c->visit( $action [, \@arguments ] )
350
351=head2 $c->visit( $class, $method, [, \@arguments ] )
352
353Almost the same as C<forward>, but does a full dispatch, instead of just
354calling the new C<$action> / C<$class-E<gt>$method>. This means that C<begin>,
355C<auto> and the method you go to are called, just like a new request.
356
357C<$c-E<gt>stash> is kept unchanged.
358
359In effect, C<visit> allows you to "wrap" another action, just as it
360would have been called by dispatching from a URL, while the analogous
361C<go> allows you to transfer control to another action as if it had
362been reached directly from a URL.
363
364=cut
365
366sub visit { my $c = shift; $c->dispatcher->visit( $c, @_ ) }
367
2f381252 368=head2 $c->go( $action [, \@arguments ] )
369
370=head2 $c->go( $class, $method, [, \@arguments ] )
371
ae0e35ee 372Almost the same as C<detach>, but does a full dispatch like C<visit>,
373instead of just calling the new C<$action> /
374C<$class-E<gt>$method>. This means that C<begin>, C<auto> and the
375method you visit are called, just like a new request.
2f381252 376
377C<$c-E<gt>stash> is kept unchanged.
378
379=cut
380
381sub go { my $c = shift; $c->dispatcher->go( $c, @_ ) }
382
b4b01a8a 383=head2 $c->response
384
385=head2 $c->res
386
cc95842f 387Returns the current L<Catalyst::Response> object, see there for details.
b4b01a8a 388
389=head2 $c->stash
390
391Returns a hashref to the stash, which may be used to store data and pass
392it between components during a request. You can also set hash keys by
393passing arguments. The stash is automatically sent to the view. The
394stash is cleared at the end of a request; it cannot be used for
86418559 395persistent storage (for this you must use a session; see
396L<Catalyst::Plugin::Session> for a complete system integrated with
397Catalyst).
b4b01a8a 398
399 $c->stash->{foo} = $bar;
400 $c->stash( { moose => 'majestic', qux => 0 } );
401 $c->stash( bar => 1, gorch => 2 ); # equivalent to passing a hashref
ac5c933b 402
b4b01a8a 403 # stash is automatically passed to the view for use in a template
cc95842f 404 $c->forward( 'MyApp::View::TT' );
b4b01a8a 405
406=cut
407
4090e3bb 408around stash => sub {
409 my $orig = shift;
b4b01a8a 410 my $c = shift;
4090e3bb 411 my $stash = $orig->($c);
b4b01a8a 412 if (@_) {
4090e3bb 413 my $new_stash = @_ > 1 ? {@_} : $_[0];
414 croak('stash takes a hash or hashref') unless ref $new_stash;
415 foreach my $key ( keys %$new_stash ) {
416 $stash->{$key} = $new_stash->{$key};
b4b01a8a 417 }
418 }
0fc2d522 419
4090e3bb 420 return $stash;
421};
0fc2d522 422
b4b01a8a 423
b5ecfcf0 424=head2 $c->error
0ef52a96 425
b5ecfcf0 426=head2 $c->error($error, ...)
0ef52a96 427
b5ecfcf0 428=head2 $c->error($arrayref)
0ef52a96 429
83a8fcac 430Returns an arrayref containing error messages. If Catalyst encounters an
431error while processing a request, it stores the error in $c->error. This
e7ad3b81 432method should only be used to store fatal error messages.
0ef52a96 433
434 my @error = @{ $c->error };
435
436Add a new error.
437
438 $c->error('Something bad happened');
439
0ef52a96 440=cut
441
442sub error {
443 my $c = shift;
444 if ( $_[0] ) {
445 my $error = ref $_[0] eq 'ARRAY' ? $_[0] : [@_];
9ce44430 446 croak @$error unless ref $c;
0ef52a96 447 push @{ $c->{error} }, @$error;
448 }
449 elsif ( defined $_[0] ) { $c->{error} = undef }
450 return $c->{error} || [];
451}
452
b4b01a8a 453
454=head2 $c->state
455
456Contains the return value of the last executed action.
457
ca81eb67 458=head2 $c->clear_errors
459
460Clear errors. You probably don't want to clear the errors unless you are
461implementing a custom error screen.
462
463This is equivalent to running
464
465 $c->error(0);
466
467=cut
468
469sub clear_errors {
470 my $c = shift;
471 $c->error(0);
472}
473
2f381252 474# search components given a name and some prefixes
475sub _comp_search_prefixes {
476 my ( $c, $name, @prefixes ) = @_;
477 my $appclass = ref $c || $c;
478 my $filter = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
0ef52a96 479
2f381252 480 # map the original component name to the sub part that we will search against
481 my %eligible = map { my $n = $_; $n =~ s{^$appclass\::[^:]+::}{}; $_ => $n; }
482 grep { /$filter/ } keys %{ $c->components };
0756fe3b 483
2f381252 484 # undef for a name will return all
485 return keys %eligible if !defined $name;
0756fe3b 486
2f381252 487 my $query = ref $name ? $name : qr/^$name$/i;
488 my @result = grep { $eligible{$_} =~ m{$query} } keys %eligible;
0756fe3b 489
2f381252 490 return map { $c->components->{ $_ } } @result if @result;
0756fe3b 491
2f381252 492 # if we were given a regexp to search against, we're done.
493 return if ref $name;
0756fe3b 494
2f381252 495 # regexp fallback
496 $query = qr/$name/i;
497 @result = map { $c->components->{ $_ } } grep { $eligible{ $_ } =~ m{$query} } keys %eligible;
0756fe3b 498
2f381252 499 # no results? try against full names
500 if( !@result ) {
501 @result = map { $c->components->{ $_ } } grep { m{$query} } keys %eligible;
502 }
0756fe3b 503
2f381252 504 # don't warn if we didn't find any results, it just might not exist
505 if( @result ) {
506 $c->log->warn( qq(Found results for "${name}" using regexp fallback.) );
507 $c->log->warn( 'Relying on the regexp fallback behavior for component resolution is unreliable and unsafe.' );
508 $c->log->warn( 'If you really want to search, pass in a regexp as the argument.' );
509 }
0756fe3b 510
2f381252 511 return @result;
0756fe3b 512}
513
ac5c933b 514# Find possible names for a prefix
3b88a455 515sub _comp_names {
516 my ( $c, @prefixes ) = @_;
3b88a455 517 my $appclass = ref $c || $c;
518
2f381252 519 my $filter = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
3b88a455 520
2f381252 521 my @names = map { s{$filter}{}; $_; } $c->_comp_search_prefixes( undef, @prefixes );
3b88a455 522 return @names;
523}
524
197bd788 525# Filter a component before returning by calling ACCEPT_CONTEXT if available
526sub _filter_component {
527 my ( $c, $comp, @args ) = @_;
2f381252 528
df543cc2 529 if ( Scalar::Util::blessed($c) && eval { $comp->can('ACCEPT_CONTEXT'); } ) {
197bd788 530 return $comp->ACCEPT_CONTEXT( $c, @args );
531 }
2f381252 532
533 return $comp;
197bd788 534}
535
f7b672ef 536=head2 COMPONENT ACCESSORS
0ef52a96 537
b5ecfcf0 538=head2 $c->controller($name)
af3ff00e 539
0ef52a96 540Gets a L<Catalyst::Controller> instance by name.
af3ff00e 541
542 $c->controller('Foo')->do_stuff;
543
86418559 544If the name is omitted, will return the controller for the dispatched
545action.
649fd1fa 546
2f381252 547If you want to search for controllers, pass in a regexp as the argument.
548
549 # find all controllers that start with Foo
550 my @foo_controllers = $c->controller(qr{^Foo});
551
552
af3ff00e 553=cut
554
555sub controller {
197bd788 556 my ( $c, $name, @args ) = @_;
2f381252 557
558 if( $name ) {
559 my @result = $c->_comp_search_prefixes( $name, qw/Controller C/ );
560 return map { $c->_filter_component( $_, @args ) } @result if ref $name;
561 return $c->_filter_component( $result[ 0 ], @args );
562 }
563
197bd788 564 return $c->component( $c->action->class );
af3ff00e 565}
566
b5ecfcf0 567=head2 $c->model($name)
fc7ec1d9 568
0ef52a96 569Gets a L<Catalyst::Model> instance by name.
570
571 $c->model('Foo')->do_stuff;
fc7ec1d9 572
72f87c4b 573Any extra arguments are directly passed to ACCEPT_CONTEXT.
574
ac5c933b 575If the name is omitted, it will look for
2f381252 576 - a model object in $c->stash->{current_model_instance}, then
a3b71f0f 577 - a model name in $c->stash->{current_model}, then
578 - a config setting 'default_model', or
579 - check if there is only one model, and return it if that's the case.
649fd1fa 580
2f381252 581If you want to search for models, pass in a regexp as the argument.
582
583 # find all models that start with Foo
584 my @foo_models = $c->model(qr{^Foo});
585
fc7ec1d9 586=cut
587
0ef52a96 588sub model {
197bd788 589 my ( $c, $name, @args ) = @_;
2f381252 590
591 if( $name ) {
592 my @result = $c->_comp_search_prefixes( $name, qw/Model M/ );
593 return map { $c->_filter_component( $_, @args ) } @result if ref $name;
594 return $c->_filter_component( $result[ 0 ], @args );
595 }
596
a3b71f0f 597 if (ref $c) {
ac5c933b 598 return $c->stash->{current_model_instance}
a3b71f0f 599 if $c->stash->{current_model_instance};
600 return $c->model( $c->stash->{current_model} )
601 if $c->stash->{current_model};
a3b71f0f 602 }
72f87c4b 603 return $c->model( $c->config->{default_model} )
604 if $c->config->{default_model};
3b88a455 605
2f381252 606 my( $comp, $rest ) = $c->_comp_search_prefixes( undef, qw/Model M/);
3b88a455 607
2f381252 608 if( $rest ) {
609 $c->log->warn( 'Calling $c->model() will return a random model unless you specify one of:' );
610 $c->log->warn( '* $c->config->{default_model} # the name of the default model to use' );
611 $c->log->warn( '* $c->stash->{current_model} # the name of the model to use for this request' );
612 $c->log->warn( '* $c->stash->{current_model_instance} # the instance of the model to use for this request' );
613 $c->log->warn( 'NB: in version 5.80, the "random" behavior will not work at all.' );
614 }
3b88a455 615
2f381252 616 return $c->_filter_component( $comp );
3b88a455 617}
618
b4b01a8a 619
b5ecfcf0 620=head2 $c->view($name)
0ef52a96 621
622Gets a L<Catalyst::View> instance by name.
fc7ec1d9 623
0ef52a96 624 $c->view('Foo')->do_stuff;
fc7ec1d9 625
72f87c4b 626Any extra arguments are directly passed to ACCEPT_CONTEXT.
627
ac5c933b 628If the name is omitted, it will look for
2f381252 629 - a view object in $c->stash->{current_view_instance}, then
a3b71f0f 630 - a view name in $c->stash->{current_view}, then
631 - a config setting 'default_view', or
632 - check if there is only one view, and return it if that's the case.
649fd1fa 633
2f381252 634If you want to search for views, pass in a regexp as the argument.
635
636 # find all views that start with Foo
637 my @foo_views = $c->view(qr{^Foo});
638
fc7ec1d9 639=cut
640
0ef52a96 641sub view {
197bd788 642 my ( $c, $name, @args ) = @_;
2f381252 643
644 if( $name ) {
645 my @result = $c->_comp_search_prefixes( $name, qw/View V/ );
646 return map { $c->_filter_component( $_, @args ) } @result if ref $name;
647 return $c->_filter_component( $result[ 0 ], @args );
648 }
649
a3b71f0f 650 if (ref $c) {
ac5c933b 651 return $c->stash->{current_view_instance}
a3b71f0f 652 if $c->stash->{current_view_instance};
653 return $c->view( $c->stash->{current_view} )
654 if $c->stash->{current_view};
a3b71f0f 655 }
72f87c4b 656 return $c->view( $c->config->{default_view} )
657 if $c->config->{default_view};
2f381252 658
659 my( $comp, $rest ) = $c->_comp_search_prefixes( undef, qw/View V/);
660
661 if( $rest ) {
662 $c->log->warn( 'Calling $c->view() will return a random view unless you specify one of:' );
663 $c->log->warn( '* $c->config->{default_view} # the name of the default view to use' );
664 $c->log->warn( '* $c->stash->{current_view} # the name of the view to use for this request' );
665 $c->log->warn( '* $c->stash->{current_view_instance} # the instance of the view to use for this request' );
666 $c->log->warn( 'NB: in version 5.80, the "random" behavior will not work at all.' );
667 }
668
669 return $c->_filter_component( $comp );
670}
671
672=head2 $c->controllers
673
674Returns the available names which can be passed to $c->controller
675
676=cut
677
678sub controllers {
679 my ( $c ) = @_;
680 return $c->_comp_names(qw/Controller C/);
0ef52a96 681}
fbcc39ad 682
b4b01a8a 683=head2 $c->models
684
685Returns the available names which can be passed to $c->model
686
687=cut
688
689sub models {
690 my ( $c ) = @_;
691 return $c->_comp_names(qw/Model M/);
692}
693
694
3b88a455 695=head2 $c->views
696
697Returns the available names which can be passed to $c->view
698
699=cut
700
701sub views {
702 my ( $c ) = @_;
703 return $c->_comp_names(qw/View V/);
704}
705
b4b01a8a 706=head2 $c->comp($name)
707
708=head2 $c->component($name)
709
cc95842f 710Gets a component object by name. This method is not recommended,
b4b01a8a 711unless you want to get a specific component by full
cc95842f 712class. C<< $c->controller >>, C<< $c->model >>, and C<< $c->view >>
b4b01a8a 713should be used instead.
714
2f381252 715If C<$name> is a regexp, a list of components matched against the full
716component name will be returned.
717
b4b01a8a 718=cut
719
720sub component {
2f381252 721 my ( $c, $name, @args ) = @_;
b4b01a8a 722
2f381252 723 if( $name ) {
724 my $comps = $c->components;
b4b01a8a 725
2f381252 726 if( !ref $name ) {
727 # is it the exact name?
728 return $c->_filter_component( $comps->{ $name }, @args )
729 if exists $comps->{ $name };
b4b01a8a 730
2f381252 731 # perhaps we just omitted "MyApp"?
732 my $composed = ( ref $c || $c ) . "::${name}";
733 return $c->_filter_component( $comps->{ $composed }, @args )
734 if exists $comps->{ $composed };
b4b01a8a 735
2f381252 736 # search all of the models, views and controllers
737 my( $comp ) = $c->_comp_search_prefixes( $name, qw/Model M Controller C View V/ );
738 return $c->_filter_component( $comp, @args ) if $comp;
739 }
740
741 # This is here so $c->comp( '::M::' ) works
742 my $query = ref $name ? $name : qr{$name}i;
b4b01a8a 743
2f381252 744 my @result = grep { m{$query} } keys %{ $c->components };
745 return map { $c->_filter_component( $_, @args ) } @result if ref $name;
b4b01a8a 746
2f381252 747 if( $result[ 0 ] ) {
748 $c->log->warn( qq(Found results for "${name}" using regexp fallback.) );
749 $c->log->warn( 'Relying on the regexp fallback behavior for component resolution' );
750 $c->log->warn( 'is unreliable and unsafe. You have been warned' );
751 return $c->_filter_component( $result[ 0 ], @args );
752 }
753
754 # I would expect to return an empty list here, but that breaks back-compat
b4b01a8a 755 }
756
2f381252 757 # fallback
b4b01a8a 758 return sort keys %{ $c->components };
759}
760
b4b01a8a 761=head2 CLASS DATA AND HELPER CLASSES
fbcc39ad 762
b5ecfcf0 763=head2 $c->config
fbcc39ad 764
0ef52a96 765Returns or takes a hashref containing the application's configuration.
766
61b1d329 767 __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } );
81557adf 768
cc95842f 769You can also use a C<YAML>, C<XML> or C<Config::General> config file
770like myapp.yml in your applications home directory. See
771L<Catalyst::Plugin::ConfigLoader>.
a6ad13b6 772
773 ---
774 db: dsn:SQLite:foo.db
775
b4b01a8a 776
3643e890 777=cut
778
4090e3bb 779around config => sub {
780 my $orig = shift;
3643e890 781 my $c = shift;
782
783 $c->log->warn("Setting config after setup has been run is not a good idea.")
784 if ( @_ and $c->setup_finished );
785
4090e3bb 786 $c->$orig(@_);
787};
3643e890 788
b5ecfcf0 789=head2 $c->log
0ef52a96 790
86418559 791Returns the logging object instance. Unless it is already set, Catalyst
792sets this up with a L<Catalyst::Log> object. To use your own log class,
793set the logger with the C<< __PACKAGE__->log >> method prior to calling
9e7673af 794C<< __PACKAGE__->setup >>.
795
796 __PACKAGE__->log( MyLogger->new );
797 __PACKAGE__->setup;
798
799And later:
0ef52a96 800
ae1e6b59 801 $c->log->info( 'Now logging with my own logger!' );
0ef52a96 802
86418559 803Your log class should implement the methods described in
804L<Catalyst::Log>.
af3ff00e 805
b4b01a8a 806
807=head2 $c->debug
808
809Overload to enable debug messages (same as -Debug option).
810
e80e8542 811Note that this is a static method, not an accessor and should be overloaded
812by declaring "sub debug { 1 }" in your MyApp.pm, not by calling $c->debug(1).
813
af3ff00e 814=cut
815
b4b01a8a 816sub debug { 0 }
817
818=head2 $c->dispatcher
819
820Returns the dispatcher instance. Stringifies to class name. See
821L<Catalyst::Dispatcher>.
822
823=head2 $c->engine
824
825Returns the engine instance. Stringifies to the class name. See
826L<Catalyst::Engine>.
827
828
f7b672ef 829=head2 UTILITY METHODS
66e28e3f 830
b5ecfcf0 831=head2 $c->path_to(@path)
01033d73 832
cc95842f 833Merges C<@path> with C<< $c->config->{home} >> and returns a
afbb9aa3 834L<Path::Class::Dir> object.
01033d73 835
836For example:
837
838 $c->path_to( 'db', 'sqlite.db' );
839
840=cut
841
842sub path_to {
843 my ( $c, @path ) = @_;
a738ab68 844 my $path = Path::Class::Dir->new( $c->config->{home}, @path );
01033d73 845 if ( -d $path ) { return $path }
a738ab68 846 else { return Path::Class::File->new( $c->config->{home}, @path ) }
01033d73 847}
848
b5ecfcf0 849=head2 $c->plugin( $name, $class, @args )
0ef52a96 850
ae1e6b59 851Helper method for plugins. It creates a classdata accessor/mutator and
852loads and instantiates the given class.
0ef52a96 853
854 MyApp->plugin( 'prototype', 'HTML::Prototype' );
855
856 $c->prototype->define_javascript_functions;
857
858=cut
859
860sub plugin {
861 my ( $class, $name, $plugin, @args ) = @_;
97b58e17 862 $class->_register_plugin( $plugin, 1 );
0ef52a96 863
864 eval { $plugin->import };
865 $class->mk_classdata($name);
866 my $obj;
867 eval { $obj = $plugin->new(@args) };
868
869 if ($@) {
870 Catalyst::Exception->throw( message =>
871 qq/Couldn't instantiate instant plugin "$plugin", "$@"/ );
872 }
873
874 $class->$name($obj);
875 $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/)
876 if $class->debug;
877}
878
b5ecfcf0 879=head2 MyApp->setup
fbcc39ad 880
e7f1cf73 881Initializes the dispatcher and engine, loads any plugins, and loads the
ae1e6b59 882model, view, and controller components. You may also specify an array
883of plugins to load here, if you choose to not load them in the C<use
884Catalyst> line.
fbcc39ad 885
0ef52a96 886 MyApp->setup;
887 MyApp->setup( qw/-Debug/ );
fbcc39ad 888
889=cut
890
891sub setup {
0319a12c 892 my ( $class, @arguments ) = @_;
5168a5fc 893 $class->log->warn("Running setup twice is not a good idea.")
894 if ( $class->setup_finished );
895
fbcc39ad 896 unless ( $class->isa('Catalyst') ) {
953b0e15 897
fbcc39ad 898 Catalyst::Exception->throw(
899 message => qq/'$class' does not inherit from Catalyst/ );
1c99e125 900 }
0319a12c 901
fbcc39ad 902 if ( $class->arguments ) {
903 @arguments = ( @arguments, @{ $class->arguments } );
904 }
905
906 # Process options
907 my $flags = {};
908
909 foreach (@arguments) {
910
911 if (/^-Debug$/) {
912 $flags->{log} =
913 ( $flags->{log} ) ? 'debug,' . $flags->{log} : 'debug';
914 }
915 elsif (/^-(\w+)=?(.*)$/) {
916 $flags->{ lc $1 } = $2;
917 }
918 else {
919 push @{ $flags->{plugins} }, $_;
920 }
921 }
922
99f187d6 923 $class->setup_home( delete $flags->{home} );
924
fbcc39ad 925 $class->setup_log( delete $flags->{log} );
926 $class->setup_plugins( delete $flags->{plugins} );
927 $class->setup_dispatcher( delete $flags->{dispatcher} );
928 $class->setup_engine( delete $flags->{engine} );
dc5f035e 929 $class->setup_stats( delete $flags->{stats} );
fbcc39ad 930
931 for my $flag ( sort keys %{$flags} ) {
932
933 if ( my $code = $class->can( 'setup_' . $flag ) ) {
934 &$code( $class, delete $flags->{$flag} );
935 }
936 else {
937 $class->log->warn(qq/Unknown flag "$flag"/);
938 }
939 }
940
0eb4af72 941 eval { require Catalyst::Devel; };
942 if( !$@ && $ENV{CATALYST_SCRIPT_GEN} && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::Devel::CATALYST_SCRIPT_GEN ) ) {
943 $class->log->warn(<<"EOF");
4ff0d824 944You are running an old script!
945
34a83d89 946 Please update by running (this will overwrite existing files):
947 catalyst.pl -force -scripts $class
948
949 or (this will not overwrite existing files):
950 catalyst.pl -scripts $class
1cf0345b 951
4ff0d824 952EOF
0eb4af72 953 }
ac5c933b 954
fbcc39ad 955 if ( $class->debug ) {
6601f2ad 956 my @plugins = map { "$_ " . ( $_->VERSION || '' ) } $class->registered_plugins;
fbcc39ad 957
958 if (@plugins) {
34d28dfd 959 my $t = Text::SimpleTable->new(74);
8c113188 960 $t->row($_) for @plugins;
1cf0345b 961 $class->log->debug( "Loaded plugins:\n" . $t->draw . "\n" );
fbcc39ad 962 }
963
964 my $dispatcher = $class->dispatcher;
965 my $engine = $class->engine;
966 my $home = $class->config->{home};
967
968 $class->log->debug(qq/Loaded dispatcher "$dispatcher"/);
969 $class->log->debug(qq/Loaded engine "$engine"/);
970
971 $home
972 ? ( -d $home )
973 ? $class->log->debug(qq/Found home "$home"/)
974 : $class->log->debug(qq/Home "$home" doesn't exist/)
975 : $class->log->debug(q/Couldn't find home/);
976 }
977
978 # Call plugins setup
979 {
980 no warnings qw/redefine/;
981 local *setup = sub { };
982 $class->setup;
983 }
984
985 # Initialize our data structure
986 $class->components( {} );
987
988 $class->setup_components;
989
990 if ( $class->debug ) {
34d28dfd 991 my $t = Text::SimpleTable->new( [ 63, 'Class' ], [ 8, 'Type' ] );
684d10ed 992 for my $comp ( sort keys %{ $class->components } ) {
993 my $type = ref $class->components->{$comp} ? 'instance' : 'class';
994 $t->row( $comp, $type );
995 }
1cf0345b 996 $class->log->debug( "Loaded components:\n" . $t->draw . "\n" )
8c113188 997 if ( keys %{ $class->components } );
fbcc39ad 998 }
999
1000 # Add our self to components, since we are also a component
96d8d513 1001 if( $class->isa('Catalyst::Controller') ){
1002 $class->components->{$class} = $class;
1003 }
fbcc39ad 1004
1005 $class->setup_actions;
1006
1007 if ( $class->debug ) {
1008 my $name = $class->config->{name} || 'Application';
1009 $class->log->info("$name powered by Catalyst $Catalyst::VERSION");
1010 }
1011 $class->log->_flush() if $class->log->can('_flush');
3643e890 1012
1013 $class->setup_finished(1);
fbcc39ad 1014}
1015
8a27f860 1016=head2 $c->uri_for( $action, \@captures?, @args?, \%query_values? )
1017
73664287 1018=head2 $c->uri_for( $path, @args?, \%query_values? )
fbcc39ad 1019
8a27f860 1020=over
fbcc39ad 1021
8a27f860 1022=item $action
8dc69021 1023
8a27f860 1024A Catalyst::Action object representing the Catalyst action you want to
1025create a URI for. To get one for an action in the current controller,
1026use C<< $c->action('someactionname') >>. To get one from different
1027controller, fetch the controller using C<< $c->controller() >>, then
1028call C<action_for> on it.
ea0e58d9 1029
9df7c5d9 1030You can maintain the arguments captured by an action (e.g.: Regex, Chained)
1031using C<< $c->req->captures >>.
1032
1033 # For the current action
1034 $c->uri_for($c->action, $c->req->captures);
1035
1036 # For the Foo action in the Bar controller
1037 $c->uri_for($c->controller->('Bar')->action_for('Foo'), $c->req->captures);
1038
fbcc39ad 1039=cut
1040
d5e3d528 1041=back
1042
fbcc39ad 1043sub uri_for {
00e6a2b7 1044 my ( $c, $path, @args ) = @_;
00e6a2b7 1045
ea0e58d9 1046 if ( Scalar::Util::blessed($path) ) { # action object
1047 my $captures = ( scalar @args && ref $args[0] eq 'ARRAY'
1048 ? shift(@args)
1049 : [] );
1050 $path = $c->dispatcher->uri_for_action($path, $captures);
1051 return undef unless defined($path);
81e75875 1052 $path = '/' if $path eq '';
ea0e58d9 1053 }
1054
51674a63 1055 undef($path) if (defined $path && $path eq '');
00e6a2b7 1056
97b58e17 1057 my $params =
1058 ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} );
8327e2e2 1059
cbb93105 1060 carp "uri_for called with undef argument" if grep { ! defined $_ } @args;
51674a63 1061 s/([^$URI::uric])/$URI::Escape::escapes{$1}/go for @args;
1062
1063 unshift(@args, $path);
1064
1065 unless (defined $path && $path =~ s!^/!!) { # in-place strip
1066 my $namespace = $c->namespace;
1067 if (defined $path) { # cheesy hack to handle path '../foo'
1068 $namespace =~ s{(?:^|/)[^/]+$}{} while $args[0] =~ s{^\.\./}{};
6601f2ad 1069 }
51674a63 1070 unshift(@args, $namespace || '');
1071 }
ac5c933b 1072
189e2a51 1073 # join args with '/', or a blank string
51674a63 1074 my $args = join('/', grep { defined($_) } @args);
1075 $args =~ s/\?/%3F/g; # STUPID STUPID SPECIAL CASE
1076 $args =~ s!^/!!;
1077 my $base = $c->req->base;
1078 my $class = ref($base);
1079 $base =~ s{(?<!/)$}{/};
1080
1081 my $query = '';
1082
1083 if (my @keys = keys %$params) {
1084 # somewhat lifted from URI::_query's query_form
1085 $query = '?'.join('&', map {
2f381252 1086 my $val = $params->{$_};
51674a63 1087 s/([;\/?:@&=+,\$\[\]%])/$URI::Escape::escapes{$1}/go;
1088 s/ /+/g;
1089 my $key = $_;
51674a63 1090 $val = '' unless defined $val;
1091 (map {
1092 $_ = "$_";
0ce485e9 1093 utf8::encode( $_ ) if utf8::is_utf8($_);
51674a63 1094 # using the URI::Escape pattern here so utf8 chars survive
1095 s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go;
1096 s/ /+/g;
1097 "${key}=$_"; } ( ref $val eq 'ARRAY' ? @$val : $val ));
1098 } @keys);
1099 }
1100
1101 my $res = bless(\"${base}${args}${query}", $class);
d3e7a648 1102 $res;
fbcc39ad 1103}
1104
b5ecfcf0 1105=head2 $c->welcome_message
ab2374d3 1106
1107Returns the Catalyst welcome HTML page.
1108
1109=cut
1110
1111sub welcome_message {
bf1f2c60 1112 my $c = shift;
1113 my $name = $c->config->{name};
1114 my $logo = $c->uri_for('/static/images/catalyst_logo.png');
1115 my $prefix = Catalyst::Utils::appprefix( ref $c );
80cdbbff 1116 $c->response->content_type('text/html; charset=utf-8');
ab2374d3 1117 return <<"EOF";
80cdbbff 1118<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
1119 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1120<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
ab2374d3 1121 <head>
85d9fce6 1122 <meta http-equiv="Content-Language" content="en" />
1123 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
ab2374d3 1124 <title>$name on Catalyst $VERSION</title>
1125 <style type="text/css">
1126 body {
ab2374d3 1127 color: #000;
1128 background-color: #eee;
1129 }
1130 div#content {
1131 width: 640px;
80cdbbff 1132 margin-left: auto;
1133 margin-right: auto;
ab2374d3 1134 margin-top: 10px;
1135 margin-bottom: 10px;
1136 text-align: left;
1137 background-color: #ccc;
1138 border: 1px solid #aaa;
ab2374d3 1139 }
d84c4dab 1140 p, h1, h2 {
ab2374d3 1141 margin-left: 20px;
1142 margin-right: 20px;
16215972 1143 font-family: verdana, tahoma, sans-serif;
ab2374d3 1144 }
d84c4dab 1145 a {
1146 font-family: verdana, tahoma, sans-serif;
1147 }
d114e033 1148 :link, :visited {
1149 text-decoration: none;
1150 color: #b00;
1151 border-bottom: 1px dotted #bbb;
1152 }
1153 :link:hover, :visited:hover {
d114e033 1154 color: #555;
1155 }
ab2374d3 1156 div#topbar {
1157 margin: 0px;
1158 }
3e82a295 1159 pre {
3e82a295 1160 margin: 10px;
1161 padding: 8px;
1162 }
ab2374d3 1163 div#answers {
1164 padding: 8px;
1165 margin: 10px;
d114e033 1166 background-color: #fff;
ab2374d3 1167 border: 1px solid #aaa;
ab2374d3 1168 }
1169 h1 {
33108eaf 1170 font-size: 0.9em;
1171 font-weight: normal;
ab2374d3 1172 text-align: center;
1173 }
1174 h2 {
1175 font-size: 1.0em;
1176 }
1177 p {
1178 font-size: 0.9em;
1179 }
ae7c5252 1180 p img {
1181 float: right;
1182 margin-left: 10px;
1183 }
9619f23c 1184 span#appname {
1185 font-weight: bold;
33108eaf 1186 font-size: 1.6em;
ab2374d3 1187 }
1188 </style>
1189 </head>
1190 <body>
1191 <div id="content">
1192 <div id="topbar">
9619f23c 1193 <h1><span id="appname">$name</span> on <a href="http://catalyst.perl.org">Catalyst</a>
d84c4dab 1194 $VERSION</h1>
ab2374d3 1195 </div>
1196 <div id="answers">
ae7c5252 1197 <p>
80cdbbff 1198 <img src="$logo" alt="Catalyst Logo" />
ae7c5252 1199 </p>
596aaffe 1200 <p>Welcome to the world of Catalyst.
f92fd545 1201 This <a href="http://en.wikipedia.org/wiki/MVC">MVC</a>
1202 framework will make web development something you had
60dd6e1d 1203 never expected it to be: Fun, rewarding, and quick.</p>
ab2374d3 1204 <h2>What to do now?</h2>
4b8cb778 1205 <p>That really depends on what <b>you</b> want to do.
ab2374d3 1206 We do, however, provide you with a few starting points.</p>
1207 <p>If you want to jump right into web development with Catalyst
2f381252 1208 you might want to start with a tutorial.</p>
b607f8a0 1209<pre>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Tutorial.pod">Catalyst::Manual::Tutorial</a></code>
596aaffe 1210</pre>
1211<p>Afterwards you can go on to check out a more complete look at our features.</p>
1212<pre>
b607f8a0 1213<code>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Intro.pod">Catalyst::Manual::Intro</a>
1214<!-- Something else should go here, but the Catalyst::Manual link seems unhelpful -->
1215</code></pre>
ab2374d3 1216 <h2>What to do next?</h2>
f5681c92 1217 <p>Next it's time to write an actual application. Use the
80cdbbff 1218 helper scripts to generate <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AController%3A%3A&amp;mode=all">controllers</a>,
60dd6e1d 1219 <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AModel%3A%3A&amp;mode=all">models</a>, and
1220 <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AView%3A%3A&amp;mode=all">views</a>;
bf1f2c60 1221 they can save you a lot of work.</p>
1222 <pre><code>script/${prefix}_create.pl -help</code></pre>
1223 <p>Also, be sure to check out the vast and growing
60dd6e1d 1224 collection of <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3APlugin%3A%3A&amp;mode=all">plugins for Catalyst on CPAN</a>;
bf1f2c60 1225 you are likely to find what you need there.
f5681c92 1226 </p>
1227
82245cc4 1228 <h2>Need help?</h2>
f5681c92 1229 <p>Catalyst has a very active community. Here are the main places to
1230 get in touch with us.</p>
16215972 1231 <ul>
1232 <li>
2b9a7d76 1233 <a href="http://dev.catalyst.perl.org">Wiki</a>
16215972 1234 </li>
1235 <li>
1236 <a href="http://lists.rawmode.org/mailman/listinfo/catalyst">Mailing-List</a>
1237 </li>
1238 <li>
4eaf7c88 1239 <a href="irc://irc.perl.org/catalyst">IRC channel #catalyst on irc.perl.org</a>
16215972 1240 </li>
1241 </ul>
ab2374d3 1242 <h2>In conclusion</h2>
ac5c933b 1243 <p>The Catalyst team hopes you will enjoy using Catalyst as much
f5681c92 1244 as we enjoyed making it. Please contact us if you have ideas
1245 for improvement or other feedback.</p>
ab2374d3 1246 </div>
1247 </div>
1248 </body>
1249</html>
1250EOF
1251}
1252
fbcc39ad 1253=head1 INTERNAL METHODS
1254
ae1e6b59 1255These methods are not meant to be used by end users.
1256
b5ecfcf0 1257=head2 $c->components
fbcc39ad 1258
e7f1cf73 1259Returns a hash of components.
fbcc39ad 1260
b5ecfcf0 1261=head2 $c->context_class
1f9cb7c1 1262
e7f1cf73 1263Returns or sets the context class.
1f9cb7c1 1264
b5ecfcf0 1265=head2 $c->counter
fbcc39ad 1266
ae1e6b59 1267Returns a hashref containing coderefs and execution counts (needed for
1268deep recursion detection).
fbcc39ad 1269
b5ecfcf0 1270=head2 $c->depth
fbcc39ad 1271
e7f1cf73 1272Returns the number of actions on the current internal execution stack.
fbcc39ad 1273
b5ecfcf0 1274=head2 $c->dispatch
fbcc39ad 1275
e7f1cf73 1276Dispatches a request to actions.
fbcc39ad 1277
1278=cut
1279
1280sub dispatch { my $c = shift; $c->dispatcher->dispatch( $c, @_ ) }
1281
b5ecfcf0 1282=head2 $c->dispatcher_class
1f9cb7c1 1283
e7f1cf73 1284Returns or sets the dispatcher class.
1f9cb7c1 1285
b5ecfcf0 1286=head2 $c->dump_these
7f92deef 1287
ae1e6b59 1288Returns a list of 2-element array references (name, structure) pairs
1289that will be dumped on the error page in debug mode.
7f92deef 1290
1291=cut
1292
1293sub dump_these {
1294 my $c = shift;
ac5c933b 1295 [ Request => $c->req ],
1296 [ Response => $c->res ],
052a2d89 1297 [ Stash => $c->stash ],
1298 [ Config => $c->config ];
7f92deef 1299}
1300
b5ecfcf0 1301=head2 $c->engine_class
1f9cb7c1 1302
e7f1cf73 1303Returns or sets the engine class.
1f9cb7c1 1304
b5ecfcf0 1305=head2 $c->execute( $class, $coderef )
fbcc39ad 1306
0ef52a96 1307Execute a coderef in given class and catch exceptions. Errors are available
1308via $c->error.
fbcc39ad 1309
1310=cut
1311
1312sub execute {
1313 my ( $c, $class, $code ) = @_;
858828dd 1314 $class = $c->component($class) || $class;
fbcc39ad 1315 $c->state(0);
a0eca838 1316
197bd788 1317 if ( $c->depth >= $RECURSION ) {
f3414019 1318 my $action = $code->reverse();
91d08727 1319 $action = "/$action" unless $action =~ /->/;
f3414019 1320 my $error = qq/Deep recursion detected calling "${action}"/;
1627551a 1321 $c->log->error($error);
1322 $c->error($error);
1323 $c->state(0);
1324 return $c->state;
1325 }
1326
dc5f035e 1327 my $stats_info = $c->_stats_start_execute( $code ) if $c->use_stats;
22247e54 1328
8767c5a3 1329 push( @{ $c->stack }, $code );
ac5c933b 1330
f3414019 1331 eval { $c->state( $code->execute( $class, $c, @{ $c->req->args } ) || 0 ) };
22247e54 1332
dc5f035e 1333 $c->_stats_finish_execute( $stats_info ) if $c->use_stats and $stats_info;
ac5c933b 1334
a6724a82 1335 my $last = pop( @{ $c->stack } );
fbcc39ad 1336
1337 if ( my $error = $@ ) {
2f381252 1338 if ( !ref($error) and $error eq $DETACH ) {
1339 die $DETACH if($c->depth > 1);
1340 }
55424863 1341 elsif ( !ref($error) and $error eq $GO ) {
1342 die $GO if($c->depth > 0);
1343 }
fbcc39ad 1344 else {
1345 unless ( ref $error ) {
91d08727 1346 no warnings 'uninitialized';
fbcc39ad 1347 chomp $error;
f59def82 1348 my $class = $last->class;
1349 my $name = $last->name;
1350 $error = qq/Caught exception in $class->$name "$error"/;
fbcc39ad 1351 }
fbcc39ad 1352 $c->error($error);
1353 $c->state(0);
1354 }
1355 }
1356 return $c->state;
1357}
1358
7a7d7af5 1359sub _stats_start_execute {
1360 my ( $c, $code ) = @_;
1361
a6724a82 1362 return if ( ( $code->name =~ /^_.*/ )
1363 && ( !$c->config->{show_internal_actions} ) );
7a7d7af5 1364
f3414019 1365 my $action_name = $code->reverse();
1366 $c->counter->{$action_name}++;
7a7d7af5 1367
f3414019 1368 my $action = $action_name;
a6724a82 1369 $action = "/$action" unless $action =~ /->/;
1370
7a7d7af5 1371 # determine if the call was the result of a forward
1372 # this is done by walking up the call stack and looking for a calling
1373 # sub of Catalyst::forward before the eval
1374 my $callsub = q{};
1375 for my $index ( 2 .. 11 ) {
1376 last
1377 if ( ( caller($index) )[0] eq 'Catalyst'
1378 && ( caller($index) )[3] eq '(eval)' );
1379
1380 if ( ( caller($index) )[3] =~ /forward$/ ) {
1381 $callsub = ( caller($index) )[3];
1382 $action = "-> $action";
1383 last;
1384 }
1385 }
1386
f3414019 1387 my $uid = $action_name . $c->counter->{$action_name};
74efc144 1388
a6724a82 1389 # is this a root-level call or a forwarded call?
1390 if ( $callsub =~ /forward$/ ) {
1391
1392 # forward, locate the caller
1393 if ( my $parent = $c->stack->[-1] ) {
69d8f33c 1394 $c->stats->profile(
ac5c933b 1395 begin => $action,
69d8f33c 1396 parent => "$parent" . $c->counter->{"$parent"},
1397 uid => $uid,
1398 );
7a7d7af5 1399 }
1400 else {
1401
a6724a82 1402 # forward with no caller may come from a plugin
69d8f33c 1403 $c->stats->profile(
1404 begin => $action,
1405 uid => $uid,
1406 );
7a7d7af5 1407 }
1408 }
a6724a82 1409 else {
ac5c933b 1410
a6724a82 1411 # root-level call
69d8f33c 1412 $c->stats->profile(
1413 begin => $action,
1414 uid => $uid,
1415 );
a6724a82 1416 }
dc5f035e 1417 return $action;
7a7d7af5 1418
7a7d7af5 1419}
1420
1421sub _stats_finish_execute {
1422 my ( $c, $info ) = @_;
69d8f33c 1423 $c->stats->profile( end => $info );
7a7d7af5 1424}
1425
3d0d6d21 1426=head2 $c->_localize_fields( sub { }, \%keys );
1427
1428=cut
1429
e63bdf38 1430#Why does this exist? This is no longer safe and WILL NOT WORK.
1431# it doesnt seem to be used anywhere. can we remove it?
3d0d6d21 1432sub _localize_fields {
1433 my ( $c, $localized, $code ) = ( @_ );
1434
1435 my $request = delete $localized->{request} || {};
1436 my $response = delete $localized->{response} || {};
ac5c933b 1437
3d0d6d21 1438 local @{ $c }{ keys %$localized } = values %$localized;
1439 local @{ $c->request }{ keys %$request } = values %$request;
1440 local @{ $c->response }{ keys %$response } = values %$response;
1441
1442 $code->();
1443}
1444
b5ecfcf0 1445=head2 $c->finalize
fbcc39ad 1446
e7f1cf73 1447Finalizes the request.
fbcc39ad 1448
1449=cut
1450
1451sub finalize {
1452 my $c = shift;
1453
369c09bc 1454 for my $error ( @{ $c->error } ) {
1455 $c->log->error($error);
1456 }
1457
5050d7a7 1458 # Allow engine to handle finalize flow (for POE)
e63bdf38 1459 my $engine = $c->engine;
1460 if ( my $code = $engine->can('finalize') ) {
1461 $engine->$code($c);
fbcc39ad 1462 }
5050d7a7 1463 else {
fbcc39ad 1464
5050d7a7 1465 $c->finalize_uploads;
fbcc39ad 1466
5050d7a7 1467 # Error
1468 if ( $#{ $c->error } >= 0 ) {
1469 $c->finalize_error;
1470 }
1471
1472 $c->finalize_headers;
fbcc39ad 1473
5050d7a7 1474 # HEAD request
1475 if ( $c->request->method eq 'HEAD' ) {
1476 $c->response->body('');
1477 }
1478
1479 $c->finalize_body;
1480 }
ac5c933b 1481
1482 if ($c->use_stats) {
596677b6 1483 my $elapsed = sprintf '%f', $c->stats->elapsed;
12bf12c0 1484 my $av = $elapsed == 0 ? '??' : sprintf '%.3f', 1 / $elapsed;
908e3d9e 1485 $c->log->info(
ac5c933b 1486 "Request took ${elapsed}s ($av/s)\n" . $c->stats->report . "\n" );
908e3d9e 1487 }
fbcc39ad 1488
1489 return $c->response->status;
1490}
1491
b5ecfcf0 1492=head2 $c->finalize_body
fbcc39ad 1493
e7f1cf73 1494Finalizes body.
fbcc39ad 1495
1496=cut
1497
1498sub finalize_body { my $c = shift; $c->engine->finalize_body( $c, @_ ) }
1499
b5ecfcf0 1500=head2 $c->finalize_cookies
fbcc39ad 1501
e7f1cf73 1502Finalizes cookies.
fbcc39ad 1503
1504=cut
1505
147821ea 1506sub finalize_cookies { my $c = shift; $c->engine->finalize_cookies( $c, @_ ) }
fbcc39ad 1507
b5ecfcf0 1508=head2 $c->finalize_error
fbcc39ad 1509
e7f1cf73 1510Finalizes error.
fbcc39ad 1511
1512=cut
1513
1514sub finalize_error { my $c = shift; $c->engine->finalize_error( $c, @_ ) }
1515
b5ecfcf0 1516=head2 $c->finalize_headers
fbcc39ad 1517
e7f1cf73 1518Finalizes headers.
fbcc39ad 1519
1520=cut
1521
1522sub finalize_headers {
1523 my $c = shift;
1524
e63bdf38 1525 my $response = $c->response; #accessor calls can add up?
1526
fbcc39ad 1527 # Check if we already finalized headers
6680c772 1528 return if $response->finalized_headers;
fbcc39ad 1529
1530 # Handle redirects
e63bdf38 1531 if ( my $location = $response->redirect ) {
fbcc39ad 1532 $c->log->debug(qq/Redirecting to "$location"/) if $c->debug;
e63bdf38 1533 $response->header( Location => $location );
a7caa492 1534
e63bdf38 1535 #Moose TODO: we should probably be using a predicate method here ?
1536 if ( !$response->body ) {
39655cdc 1537 # Add a default body if none is already present
e63bdf38 1538 $response->body(
e422816e 1539 qq{<html><body><p>This item has moved <a href="$location">here</a>.</p></body></html>}
39655cdc 1540 );
1541 }
fbcc39ad 1542 }
1543
1544 # Content-Length
e63bdf38 1545 if ( $response->body && !$response->content_length ) {
775878ac 1546
8f62c91a 1547 # get the length from a filehandle
e63bdf38 1548 if ( blessed( $response->body ) && $response->body->can('read') )
197bd788 1549 {
e63bdf38 1550 my $stat = stat $response->body;
3b6a1db1 1551 if ( $stat && $stat->size > 0 ) {
e63bdf38 1552 $response->content_length( $stat->size );
8f62c91a 1553 }
1554 else {
775878ac 1555 $c->log->warn('Serving filehandle without a content-length');
8f62c91a 1556 }
1557 }
1558 else {
b5d7a61f 1559 # everything should be bytes at this point, but just in case
e63bdf38 1560 $response->content_length( bytes::length( $response->body ) );
8f62c91a 1561 }
fbcc39ad 1562 }
1563
1564 # Errors
e63bdf38 1565 if ( $response->status =~ /^(1\d\d|[23]04)$/ ) {
1566 $response->headers->remove_header("Content-Length");
1567 $response->body('');
fbcc39ad 1568 }
1569
1570 $c->finalize_cookies;
1571
1572 $c->engine->finalize_headers( $c, @_ );
1573
1574 # Done
6680c772 1575 $response->finalized_headers(1);
fbcc39ad 1576}
1577
b5ecfcf0 1578=head2 $c->finalize_output
fbcc39ad 1579
1580An alias for finalize_body.
1581
b5ecfcf0 1582=head2 $c->finalize_read
fbcc39ad 1583
e7f1cf73 1584Finalizes the input after reading is complete.
fbcc39ad 1585
1586=cut
1587
1588sub finalize_read { my $c = shift; $c->engine->finalize_read( $c, @_ ) }
1589
b5ecfcf0 1590=head2 $c->finalize_uploads
fbcc39ad 1591
ae1e6b59 1592Finalizes uploads. Cleans up any temporary files.
fbcc39ad 1593
1594=cut
1595
1596sub finalize_uploads { my $c = shift; $c->engine->finalize_uploads( $c, @_ ) }
1597
b5ecfcf0 1598=head2 $c->get_action( $action, $namespace )
fbcc39ad 1599
e7f1cf73 1600Gets an action in a given namespace.
fbcc39ad 1601
1602=cut
1603
684d10ed 1604sub get_action { my $c = shift; $c->dispatcher->get_action(@_) }
fbcc39ad 1605
b5ecfcf0 1606=head2 $c->get_actions( $action, $namespace )
a9dc674c 1607
ae1e6b59 1608Gets all actions of a given name in a namespace and all parent
1609namespaces.
a9dc674c 1610
1611=cut
1612
1613sub get_actions { my $c = shift; $c->dispatcher->get_actions( $c, @_ ) }
1614
f7b672ef 1615=head2 $c->handle_request( $class, @arguments )
fbcc39ad 1616
e7f1cf73 1617Called to handle each HTTP request.
fbcc39ad 1618
1619=cut
1620
1621sub handle_request {
1622 my ( $class, @arguments ) = @_;
1623
1624 # Always expect worst case!
1625 my $status = -1;
1626 eval {
dea1884f 1627 if ($class->debug) {
908e3d9e 1628 my $secs = time - $START || 1;
1629 my $av = sprintf '%.3f', $COUNT / $secs;
1630 my $time = localtime time;
1631 $class->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***");
dea1884f 1632 }
908e3d9e 1633
1634 my $c = $class->prepare(@arguments);
1635 $c->dispatch;
ac5c933b 1636 $status = $c->finalize;
fbcc39ad 1637 };
1638
1639 if ( my $error = $@ ) {
1640 chomp $error;
1641 $class->log->error(qq/Caught exception in engine "$error"/);
1642 }
1643
1644 $COUNT++;
6680c772 1645
1646 if(my $coderef = $class->log->can('_flush')){
1647 $class->log->$coderef();
1648 }
fbcc39ad 1649 return $status;
1650}
1651
b5ecfcf0 1652=head2 $c->prepare( @arguments )
fbcc39ad 1653
ae1e6b59 1654Creates a Catalyst context from an engine-specific request (Apache, CGI,
1655etc.).
fbcc39ad 1656
1657=cut
1658
1659sub prepare {
1660 my ( $class, @arguments ) = @_;
1661
6680c772 1662 # XXX
1663 # After the app/ctxt split, this should become an attribute based on something passed
1664 # into the application.
3cec521a 1665 $class->context_class( ref $class || $class ) unless $class->context_class;
6680c772 1666
1667 my $c = $class->context_class->new({});
1668
1669 # For on-demand data
1670 $c->request->_context($c);
1671 $c->response->_context($c);
fbcc39ad 1672
b6d4ee6e 1673 #surely this is not the most efficient way to do things...
dc5f035e 1674 $c->stats($class->stats_class->new)->enable($c->use_stats);
908e3d9e 1675 if ( $c->debug ) {
ac5c933b 1676 $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
908e3d9e 1677 }
1678
e63bdf38 1679 #XXX reuse coderef from can
5050d7a7 1680 # Allow engine to direct the prepare flow (for POE)
1681 if ( $c->engine->can('prepare') ) {
1682 $c->engine->prepare( $c, @arguments );
1683 }
1684 else {
1685 $c->prepare_request(@arguments);
1686 $c->prepare_connection;
1687 $c->prepare_query_parameters;
1688 $c->prepare_headers;
1689 $c->prepare_cookies;
1690 $c->prepare_path;
1691
878b821c 1692 # Prepare the body for reading, either by prepare_body
1693 # or the user, if they are using $c->read
1694 $c->prepare_read;
ac5c933b 1695
878b821c 1696 # Parse the body unless the user wants it on-demand
1697 unless ( $c->config->{parse_on_demand} ) {
1698 $c->prepare_body;
1699 }
5050d7a7 1700 }
fbcc39ad 1701
fbcc39ad 1702 my $method = $c->req->method || '';
2f381252 1703 my $path = $c->req->path;
1704 $path = '/' unless length $path;
fbcc39ad 1705 my $address = $c->req->address || '';
1706
e3a13771 1707 $c->log->debug(qq/"$method" request for "$path" from "$address"/)
fbcc39ad 1708 if $c->debug;
1709
e3a13771 1710 $c->prepare_action;
1711
fbcc39ad 1712 return $c;
1713}
1714
b5ecfcf0 1715=head2 $c->prepare_action
fbcc39ad 1716
b4b01a8a 1717Prepares action. See L<Catalyst::Dispatcher>.
fbcc39ad 1718
1719=cut
1720
1721sub prepare_action { my $c = shift; $c->dispatcher->prepare_action( $c, @_ ) }
1722
b5ecfcf0 1723=head2 $c->prepare_body
fbcc39ad 1724
e7f1cf73 1725Prepares message body.
fbcc39ad 1726
1727=cut
1728
1729sub prepare_body {
1730 my $c = shift;
1731
e63bdf38 1732 #Moose TODO: what is _body ??
fbcc39ad 1733 # Do we run for the first time?
1734 return if defined $c->request->{_body};
1735
1736 # Initialize on-demand data
1737 $c->engine->prepare_body( $c, @_ );
1738 $c->prepare_parameters;
1739 $c->prepare_uploads;
1740
1741 if ( $c->debug && keys %{ $c->req->body_parameters } ) {
34d28dfd 1742 my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
fbcc39ad 1743 for my $key ( sort keys %{ $c->req->body_parameters } ) {
1744 my $param = $c->req->body_parameters->{$key};
1745 my $value = defined($param) ? $param : '';
8c113188 1746 $t->row( $key,
fbcc39ad 1747 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1748 }
1749 $c->log->debug( "Body Parameters are:\n" . $t->draw );
1750 }
1751}
1752
b5ecfcf0 1753=head2 $c->prepare_body_chunk( $chunk )
4bd82c41 1754
e7f1cf73 1755Prepares a chunk of data before sending it to L<HTTP::Body>.
4bd82c41 1756
b4b01a8a 1757See L<Catalyst::Engine>.
1758
4bd82c41 1759=cut
1760
4f5ebacd 1761sub prepare_body_chunk {
1762 my $c = shift;
4bd82c41 1763 $c->engine->prepare_body_chunk( $c, @_ );
1764}
1765
b5ecfcf0 1766=head2 $c->prepare_body_parameters
fbcc39ad 1767
e7f1cf73 1768Prepares body parameters.
fbcc39ad 1769
1770=cut
1771
1772sub prepare_body_parameters {
1773 my $c = shift;
1774 $c->engine->prepare_body_parameters( $c, @_ );
1775}
1776
b5ecfcf0 1777=head2 $c->prepare_connection
fbcc39ad 1778
e7f1cf73 1779Prepares connection.
fbcc39ad 1780
1781=cut
1782
1783sub prepare_connection {
1784 my $c = shift;
1785 $c->engine->prepare_connection( $c, @_ );
1786}
1787
b5ecfcf0 1788=head2 $c->prepare_cookies
fbcc39ad 1789
e7f1cf73 1790Prepares cookies.
fbcc39ad 1791
1792=cut
1793
1794sub prepare_cookies { my $c = shift; $c->engine->prepare_cookies( $c, @_ ) }
1795
b5ecfcf0 1796=head2 $c->prepare_headers
fbcc39ad 1797
e7f1cf73 1798Prepares headers.
fbcc39ad 1799
1800=cut
1801
1802sub prepare_headers { my $c = shift; $c->engine->prepare_headers( $c, @_ ) }
1803
b5ecfcf0 1804=head2 $c->prepare_parameters
fbcc39ad 1805
e7f1cf73 1806Prepares parameters.
fbcc39ad 1807
1808=cut
1809
1810sub prepare_parameters {
1811 my $c = shift;
1812 $c->prepare_body_parameters;
1813 $c->engine->prepare_parameters( $c, @_ );
1814}
1815
b5ecfcf0 1816=head2 $c->prepare_path
fbcc39ad 1817
e7f1cf73 1818Prepares path and base.
fbcc39ad 1819
1820=cut
1821
1822sub prepare_path { my $c = shift; $c->engine->prepare_path( $c, @_ ) }
1823
b5ecfcf0 1824=head2 $c->prepare_query_parameters
fbcc39ad 1825
e7f1cf73 1826Prepares query parameters.
fbcc39ad 1827
1828=cut
1829
1830sub prepare_query_parameters {
1831 my $c = shift;
1832
1833 $c->engine->prepare_query_parameters( $c, @_ );
1834
1835 if ( $c->debug && keys %{ $c->request->query_parameters } ) {
34d28dfd 1836 my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
fbcc39ad 1837 for my $key ( sort keys %{ $c->req->query_parameters } ) {
1838 my $param = $c->req->query_parameters->{$key};
1839 my $value = defined($param) ? $param : '';
8c113188 1840 $t->row( $key,
fbcc39ad 1841 ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
1842 }
1843 $c->log->debug( "Query Parameters are:\n" . $t->draw );
1844 }
1845}
1846
b5ecfcf0 1847=head2 $c->prepare_read
fbcc39ad 1848
e7f1cf73 1849Prepares the input for reading.
fbcc39ad 1850
1851=cut
1852
1853sub prepare_read { my $c = shift; $c->engine->prepare_read( $c, @_ ) }
1854
b5ecfcf0 1855=head2 $c->prepare_request
fbcc39ad 1856
e7f1cf73 1857Prepares the engine request.
fbcc39ad 1858
1859=cut
1860
1861sub prepare_request { my $c = shift; $c->engine->prepare_request( $c, @_ ) }
1862
b5ecfcf0 1863=head2 $c->prepare_uploads
fbcc39ad 1864
e7f1cf73 1865Prepares uploads.
fbcc39ad 1866
1867=cut
1868
1869sub prepare_uploads {
1870 my $c = shift;
1871
1872 $c->engine->prepare_uploads( $c, @_ );
1873
1874 if ( $c->debug && keys %{ $c->request->uploads } ) {
8c113188 1875 my $t = Text::SimpleTable->new(
34d28dfd 1876 [ 12, 'Parameter' ],
1877 [ 26, 'Filename' ],
8c113188 1878 [ 18, 'Type' ],
1879 [ 9, 'Size' ]
1880 );
fbcc39ad 1881 for my $key ( sort keys %{ $c->request->uploads } ) {
1882 my $upload = $c->request->uploads->{$key};
1883 for my $u ( ref $upload eq 'ARRAY' ? @{$upload} : ($upload) ) {
8c113188 1884 $t->row( $key, $u->filename, $u->type, $u->size );
fbcc39ad 1885 }
1886 }
1887 $c->log->debug( "File Uploads are:\n" . $t->draw );
1888 }
1889}
1890
b5ecfcf0 1891=head2 $c->prepare_write
fbcc39ad 1892
e7f1cf73 1893Prepares the output for writing.
fbcc39ad 1894
1895=cut
1896
1897sub prepare_write { my $c = shift; $c->engine->prepare_write( $c, @_ ) }
1898
b5ecfcf0 1899=head2 $c->request_class
1f9cb7c1 1900
e7f1cf73 1901Returns or sets the request class.
1f9cb7c1 1902
b5ecfcf0 1903=head2 $c->response_class
1f9cb7c1 1904
e7f1cf73 1905Returns or sets the response class.
1f9cb7c1 1906
b5ecfcf0 1907=head2 $c->read( [$maxlength] )
fbcc39ad 1908
ae1e6b59 1909Reads a chunk of data from the request body. This method is designed to
1910be used in a while loop, reading C<$maxlength> bytes on every call.
1911C<$maxlength> defaults to the size of the request if not specified.
fbcc39ad 1912
cc95842f 1913You have to set C<< MyApp->config->{parse_on_demand} >> to use this
ae1e6b59 1914directly.
fbcc39ad 1915
878b821c 1916Warning: If you use read(), Catalyst will not process the body,
1917so you will not be able to access POST parameters or file uploads via
1918$c->request. You must handle all body parsing yourself.
1919
fbcc39ad 1920=cut
1921
1922sub read { my $c = shift; return $c->engine->read( $c, @_ ) }
1923
b5ecfcf0 1924=head2 $c->run
fbcc39ad 1925
1926Starts the engine.
1927
1928=cut
1929
1930sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
1931
b5ecfcf0 1932=head2 $c->set_action( $action, $code, $namespace, $attrs )
fbcc39ad 1933
e7f1cf73 1934Sets an action in a given namespace.
fbcc39ad 1935
1936=cut
1937
1938sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) }
1939
b5ecfcf0 1940=head2 $c->setup_actions($component)
fbcc39ad 1941
e7f1cf73 1942Sets up actions for a component.
fbcc39ad 1943
1944=cut
1945
1946sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
1947
b5ecfcf0 1948=head2 $c->setup_components
fbcc39ad 1949
86418559 1950Sets up components. Specify a C<setup_components> config option to pass
1951additional options directly to L<Module::Pluggable>. To add additional
1952search paths, specify a key named C<search_extra> as an array
1953reference. Items in the array beginning with C<::> will have the
18de900e 1954application class name prepended to them.
fbcc39ad 1955
2f381252 1956All components found will also have any
1957L<Devel::InnerPackage|inner packages> loaded and set up as components.
1958Note, that modules which are B<not> an I<inner package> of the main
1959file namespace loaded will not be instantiated as components.
1960
fbcc39ad 1961=cut
1962
1963sub setup_components {
1964 my $class = shift;
1965
18de900e 1966 my @paths = qw( ::Controller ::C ::Model ::M ::View ::V );
1967 my $config = $class->config->{ setup_components };
1968 my $extra = delete $config->{ search_extra } || [];
ac5c933b 1969
18de900e 1970 push @paths, @$extra;
ac5c933b 1971
364d7324 1972 my $locator = Module::Pluggable::Object->new(
18de900e 1973 search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
1974 %$config
364d7324 1975 );
b94b200c 1976
1977 my @comps = sort { length $a <=> length $b } $locator->plugins;
1978 my %comps = map { $_ => 1 } @comps;
ac5c933b 1979
b94b200c 1980 for my $component ( @comps ) {
dd91afb5 1981
1982 # We pass ignore_loaded here so that overlay files for (e.g.)
1983 # Model::DBI::Schema sub-classes are loaded - if it's in @comps
1984 # we know M::P::O found a file on disk so this is safe
1985
f5a4863c 1986 Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
1987 #Class::MOP::load_class($component);
364d7324 1988
1989 my $module = $class->setup_component( $component );
1990 my %modules = (
1991 $component => $module,
1992 map {
1993 $_ => $class->setup_component( $_ )
ac5c933b 1994 } grep {
b94b200c 1995 not exists $comps{$_}
364d7324 1996 } Devel::InnerPackage::list_packages( $component )
1997 );
ac5c933b 1998
364d7324 1999 for my $key ( keys %modules ) {
2000 $class->components->{ $key } = $modules{ $key };
fbcc39ad 2001 }
364d7324 2002 }
2003}
fbcc39ad 2004
364d7324 2005=head2 $c->setup_component
fbcc39ad 2006
364d7324 2007=cut
fbcc39ad 2008
364d7324 2009sub setup_component {
2010 my( $class, $component ) = @_;
fbcc39ad 2011
364d7324 2012 unless ( $component->can( 'COMPONENT' ) ) {
2013 return $component;
2014 }
fbcc39ad 2015
364d7324 2016 my $suffix = Catalyst::Utils::class2classsuffix( $component );
2017 my $config = $class->config->{ $suffix } || {};
fbcc39ad 2018
364d7324 2019 my $instance = eval { $component->COMPONENT( $class, $config ); };
fbcc39ad 2020
2021 if ( my $error = $@ ) {
fbcc39ad 2022 chomp $error;
fbcc39ad 2023 Catalyst::Exception->throw(
364d7324 2024 message => qq/Couldn't instantiate component "$component", "$error"/
2025 );
fbcc39ad 2026 }
2027
364d7324 2028 Catalyst::Exception->throw(
2029 message =>
2030 qq/Couldn't instantiate component "$component", "COMPONENT() didn't return an object-like value"/
84ff88cf 2031 ) unless blessed($instance);
364d7324 2032
2033 return $instance;
fbcc39ad 2034}
2035
b5ecfcf0 2036=head2 $c->setup_dispatcher
fbcc39ad 2037
ae1e6b59 2038Sets up dispatcher.
2039
fbcc39ad 2040=cut
2041
2042sub setup_dispatcher {
2043 my ( $class, $dispatcher ) = @_;
2044
2045 if ($dispatcher) {
2046 $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
2047 }
2048
cb69249e 2049 if ( my $env = Catalyst::Utils::env_value( $class, 'DISPATCHER' ) ) {
2050 $dispatcher = 'Catalyst::Dispatcher::' . $env;
fbcc39ad 2051 }
2052
2053 unless ($dispatcher) {
cb0354c6 2054 $dispatcher = $class->dispatcher_class;
fbcc39ad 2055 }
2056
e63bdf38 2057 Class::MOP::load_class($dispatcher);
fbcc39ad 2058
2059 # dispatcher instance
2060 $class->dispatcher( $dispatcher->new );
2061}
2062
b5ecfcf0 2063=head2 $c->setup_engine
fbcc39ad 2064
ae1e6b59 2065Sets up engine.
2066
fbcc39ad 2067=cut
2068
2069sub setup_engine {
2070 my ( $class, $engine ) = @_;
2071
2072 if ($engine) {
2073 $engine = 'Catalyst::Engine::' . $engine;
2074 }
2075
cb69249e 2076 if ( my $env = Catalyst::Utils::env_value( $class, 'ENGINE' ) ) {
2077 $engine = 'Catalyst::Engine::' . $env;
fbcc39ad 2078 }
2079
9b0a3e0f 2080 if ( $ENV{MOD_PERL} ) {
fbcc39ad 2081
2082 # create the apache method
84ff88cf 2083 $class->meta->add_method('apache' => sub { shift->engine->apache });
fbcc39ad 2084
2085 my ( $software, $version ) =
2086 $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
2087
2088 $version =~ s/_//g;
2089 $version =~ s/(\.[^.]+)\./$1/g;
2090
2091 if ( $software eq 'mod_perl' ) {
2092
9b0a3e0f 2093 if ( !$engine ) {
22247e54 2094
9b0a3e0f 2095 if ( $version >= 1.99922 ) {
2096 $engine = 'Catalyst::Engine::Apache2::MP20';
2097 }
22247e54 2098
9b0a3e0f 2099 elsif ( $version >= 1.9901 ) {
2100 $engine = 'Catalyst::Engine::Apache2::MP19';
2101 }
22247e54 2102
9b0a3e0f 2103 elsif ( $version >= 1.24 ) {
2104 $engine = 'Catalyst::Engine::Apache::MP13';
2105 }
22247e54 2106
9b0a3e0f 2107 else {
2108 Catalyst::Exception->throw( message =>
2109 qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
2110 }
fbcc39ad 2111
fbcc39ad 2112 }
2113
2114 # install the correct mod_perl handler
2115 if ( $version >= 1.9901 ) {
2116 *handler = sub : method {
2117 shift->handle_request(@_);
2118 };
2119 }
2120 else {
2121 *handler = sub ($$) { shift->handle_request(@_) };
2122 }
2123
2124 }
2125
2126 elsif ( $software eq 'Zeus-Perl' ) {
2127 $engine = 'Catalyst::Engine::Zeus';
2128 }
2129
2130 else {
2131 Catalyst::Exception->throw(
2132 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/ );
2133 }
2134 }
2135
2136 unless ($engine) {
cb0354c6 2137 $engine = $class->engine_class;
fbcc39ad 2138 }
2139
e63bdf38 2140 Class::MOP::load_class($engine);
2141 #unless (Class::Inspector->loaded($engine)) {
2142 # require Class::Inspector->filename($engine);
2143 #}
0e7f5826 2144
d54484bf 2145 # check for old engines that are no longer compatible
2146 my $old_engine;
0e7f5826 2147 if ( $engine->isa('Catalyst::Engine::Apache')
2148 && !Catalyst::Engine::Apache->VERSION )
d54484bf 2149 {
2150 $old_engine = 1;
2151 }
0e7f5826 2152
d54484bf 2153 elsif ( $engine->isa('Catalyst::Engine::Server::Base')
0e7f5826 2154 && Catalyst::Engine::Server->VERSION le '0.02' )
d54484bf 2155 {
2156 $old_engine = 1;
2157 }
0e7f5826 2158
2159 elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
2160 && $engine->VERSION eq '0.01' )
d54484bf 2161 {
2162 $old_engine = 1;
2163 }
0e7f5826 2164
2165 elsif ($engine->isa('Catalyst::Engine::Zeus')
2166 && $engine->VERSION eq '0.01' )
d54484bf 2167 {
2168 $old_engine = 1;
2169 }
fbcc39ad 2170
d54484bf 2171 if ($old_engine) {
2172 Catalyst::Exception->throw( message =>
0e7f5826 2173 qq/Engine "$engine" is not supported by this version of Catalyst/
d54484bf 2174 );
2175 }
0e7f5826 2176
fbcc39ad 2177 # engine instance
2178 $class->engine( $engine->new );
2179}
2180
b5ecfcf0 2181=head2 $c->setup_home
fbcc39ad 2182
ae1e6b59 2183Sets up the home directory.
2184
fbcc39ad 2185=cut
2186
2187sub setup_home {
2188 my ( $class, $home ) = @_;
2189
cb69249e 2190 if ( my $env = Catalyst::Utils::env_value( $class, 'HOME' ) ) {
2191 $home = $env;
fbcc39ad 2192 }
2193
b6d4ee6e 2194 $home ||= Catalyst::Utils::home($class);
fbcc39ad 2195
2196 if ($home) {
e63bdf38 2197 #I remember recently being scolded for assigning config values like this
fbcc39ad 2198 $class->config->{home} ||= $home;
a738ab68 2199 $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
fbcc39ad 2200 }
2201}
2202
b5ecfcf0 2203=head2 $c->setup_log
fbcc39ad 2204
ae1e6b59 2205Sets up log.
2206
fbcc39ad 2207=cut
2208
2209sub setup_log {
2210 my ( $class, $debug ) = @_;
2211
2212 unless ( $class->log ) {
2213 $class->log( Catalyst::Log->new );
2214 }
af3ff00e 2215
cb69249e 2216 my $env_debug = Catalyst::Utils::env_value( $class, 'DEBUG' );
2217 if ( defined($env_debug) ? $env_debug : $debug ) {
84ff88cf 2218 $class->meta->add_method('debug' => sub { 1 });
fbcc39ad 2219 $class->log->debug('Debug messages enabled');
2220 }
2221}
2222
b5ecfcf0 2223=head2 $c->setup_plugins
fbcc39ad 2224
ae1e6b59 2225Sets up plugins.
2226
fbcc39ad 2227=cut
2228
dc5f035e 2229=head2 $c->setup_stats
2230
2231Sets up timing statistics class.
2232
2233=cut
2234
2235sub setup_stats {
2236 my ( $class, $stats ) = @_;
2237
2238 Catalyst::Utils::ensure_class_loaded($class->stats_class);
2239
2240 my $env = Catalyst::Utils::env_value( $class, 'STATS' );
2241 if ( defined($env) ? $env : ($stats || $class->debug ) ) {
84ff88cf 2242 $class->meta->add_method('use_stats' => sub { 1 });
b01f0c69 2243 $class->log->debug('Statistics enabled');
dc5f035e 2244 }
2245}
2246
2247
ac5c933b 2248=head2 $c->registered_plugins
836e1134 2249
2250Returns a sorted list of the plugins which have either been stated in the
2251import list or which have been added via C<< MyApp->plugin(@args); >>.
2252
2253If passed a given plugin name, it will report a boolean value indicating
2254whether or not that plugin is loaded. A fully qualified name is required if
2255the plugin name does not begin with C<Catalyst::Plugin::>.
2256
2257 if ($c->registered_plugins('Some::Plugin')) {
2258 ...
2259 }
2260
2261=cut
fbcc39ad 2262
836e1134 2263{
97b58e17 2264
2265 sub registered_plugins {
836e1134 2266 my $proto = shift;
197bd788 2267 return sort keys %{ $proto->_plugins } unless @_;
836e1134 2268 my $plugin = shift;
d0d4d785 2269 return 1 if exists $proto->_plugins->{$plugin};
2270 return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"};
836e1134 2271 }
fbcc39ad 2272
836e1134 2273 sub _register_plugin {
2274 my ( $proto, $plugin, $instant ) = @_;
2275 my $class = ref $proto || $proto;
fbcc39ad 2276
dd91afb5 2277 # no ignore_loaded here, the plugin may already have been
2278 # defined in memory and we don't want to error on "no file" if so
2279
b6d4ee6e 2280 Class::MOP::load_class( $plugin );
fbcc39ad 2281
197bd788 2282 $proto->_plugins->{$plugin} = 1;
836e1134 2283 unless ($instant) {
fbcc39ad 2284 no strict 'refs';
5fb67d52 2285 if( $class->can('meta') ){
2286 my @superclasses = ($plugin, $class->meta->superclasses );
2287 $class->meta->superclasses(@superclasses);
2288 } else {
2289 unshift @{"$class\::ISA"}, $plugin;
2290 }
fbcc39ad 2291 }
836e1134 2292 return $class;
2293 }
2294
2295 sub setup_plugins {
2296 my ( $class, $plugins ) = @_;
2297
d0d4d785 2298 $class->_plugins( {} ) unless $class->_plugins;
836e1134 2299 $plugins ||= [];
2300 for my $plugin ( reverse @$plugins ) {
2301
2302 unless ( $plugin =~ s/\A\+// ) {
2303 $plugin = "Catalyst::Plugin::$plugin";
2304 }
2305
2306 $class->_register_plugin($plugin);
2307 }
fbcc39ad 2308 }
2309}
2310
b5ecfcf0 2311=head2 $c->stack
8767c5a3 2312
86418559 2313Returns an arrayref of the internal execution stack (actions that are
2314currently executing).
8767c5a3 2315
dc5f035e 2316=head2 $c->stats_class
2317
2318Returns or sets the stats (timing statistics) class.
2319
2320=head2 $c->use_stats
2321
2322Returns 1 when stats collection is enabled. Stats collection is enabled
2323when the -Stats options is set, debug is on or when the <MYAPP>_STATS
2324environment variable is set.
2325
2326Note that this is a static method, not an accessor and should be overloaded
2327by declaring "sub use_stats { 1 }" in your MyApp.pm, not by calling $c->use_stats(1).
2328
2329=cut
2330
2331sub use_stats { 0 }
2332
2333
b5ecfcf0 2334=head2 $c->write( $data )
fbcc39ad 2335
ae1e6b59 2336Writes $data to the output stream. When using this method directly, you
2337will need to manually set the C<Content-Length> header to the length of
2338your output data, if known.
fbcc39ad 2339
2340=cut
2341
4f5ebacd 2342sub write {
2343 my $c = shift;
2344
2345 # Finalize headers if someone manually writes output
2346 $c->finalize_headers;
2347
2348 return $c->engine->write( $c, @_ );
2349}
fbcc39ad 2350
b5ecfcf0 2351=head2 version
bf88a181 2352
ae1e6b59 2353Returns the Catalyst version number. Mostly useful for "powered by"
2354messages in template systems.
bf88a181 2355
2356=cut
2357
2358sub version { return $Catalyst::VERSION }
2359
b0bb11ec 2360=head1 INTERNAL ACTIONS
2361
ae1e6b59 2362Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
2363C<_ACTION>, and C<_END>. These are by default not shown in the private
3e705254 2364action table, but you can make them visible with a config parameter.
b0bb11ec 2365
2366 MyApp->config->{show_internal_actions} = 1;
2367
d2ee9760 2368=head1 CASE SENSITIVITY
2369
3e705254 2370By default Catalyst is not case sensitive, so C<MyApp::C::FOO::Bar> is
ae1e6b59 2371mapped to C</foo/bar>. You can activate case sensitivity with a config
3e705254 2372parameter.
d2ee9760 2373
2374 MyApp->config->{case_sensitive} = 1;
2375
3e705254 2376This causes C<MyApp::C::Foo::Bar> to map to C</Foo/Bar>.
fbcc39ad 2377
2378=head1 ON-DEMAND PARSER
2379
2380The request body is usually parsed at the beginning of a request,
878b821c 2381but if you want to handle input yourself, you can enable on-demand
2382parsing with a config parameter.
fbcc39ad 2383
2384 MyApp->config->{parse_on_demand} = 1;
ac5c933b 2385
fbcc39ad 2386=head1 PROXY SUPPORT
2387
ae1e6b59 2388Many production servers operate using the common double-server approach,
2389with a lightweight frontend web server passing requests to a larger
2390backend server. An application running on the backend server must deal
2391with two problems: the remote user always appears to be C<127.0.0.1> and
2392the server's hostname will appear to be C<localhost> regardless of the
2393virtual host that the user connected through.
fbcc39ad 2394
ae1e6b59 2395Catalyst will automatically detect this situation when you are running
2396the frontend and backend servers on the same machine. The following
2397changes are made to the request.
fbcc39ad 2398
ac5c933b 2399 $c->req->address is set to the user's real IP address, as read from
ae1e6b59 2400 the HTTP X-Forwarded-For header.
ac5c933b 2401
ae1e6b59 2402 The host value for $c->req->base and $c->req->uri is set to the real
2403 host, as read from the HTTP X-Forwarded-Host header.
fbcc39ad 2404
3e705254 2405Obviously, your web server must support these headers for this to work.
fbcc39ad 2406
ae1e6b59 2407In a more complex server farm environment where you may have your
2408frontend proxy server(s) on different machines, you will need to set a
2409configuration option to tell Catalyst to read the proxied data from the
2410headers.
fbcc39ad 2411
2412 MyApp->config->{using_frontend_proxy} = 1;
ac5c933b 2413
fbcc39ad 2414If you do not wish to use the proxy support at all, you may set:
d1a31ac6 2415
fbcc39ad 2416 MyApp->config->{ignore_frontend_proxy} = 1;
2417
2418=head1 THREAD SAFETY
2419
86418559 2420Catalyst has been tested under Apache 2's threading C<mpm_worker>,
2421C<mpm_winnt>, and the standalone forking HTTP server on Windows. We
2422believe the Catalyst core to be thread-safe.
fbcc39ad 2423
2424If you plan to operate in a threaded environment, remember that all other
3e705254 2425modules you are using must also be thread-safe. Some modules, most notably
2426L<DBD::SQLite>, are not thread-safe.
d1a31ac6 2427
3cb1db8c 2428=head1 SUPPORT
2429
2430IRC:
2431
4eaf7c88 2432 Join #catalyst on irc.perl.org.
3cb1db8c 2433
3e705254 2434Mailing Lists:
3cb1db8c 2435
2436 http://lists.rawmode.org/mailman/listinfo/catalyst
2437 http://lists.rawmode.org/mailman/listinfo/catalyst-dev
1985c30b 2438
432d507d 2439Web:
2440
2441 http://catalyst.perl.org
2442
0ef52a96 2443Wiki:
2444
2445 http://dev.catalyst.perl.org
2446
fc7ec1d9 2447=head1 SEE ALSO
2448
829a28ca 2449=head2 L<Task::Catalyst> - All you need to start with Catalyst
2450
b5ecfcf0 2451=head2 L<Catalyst::Manual> - The Catalyst Manual
e7f1cf73 2452
b5ecfcf0 2453=head2 L<Catalyst::Component>, L<Catalyst::Base> - Base classes for components
61b1e958 2454
b5ecfcf0 2455=head2 L<Catalyst::Engine> - Core engine
61b1e958 2456
b5ecfcf0 2457=head2 L<Catalyst::Log> - Log class.
61b1e958 2458
b5ecfcf0 2459=head2 L<Catalyst::Request> - Request object
61b1e958 2460
b5ecfcf0 2461=head2 L<Catalyst::Response> - Response object
61b1e958 2462
b5ecfcf0 2463=head2 L<Catalyst::Test> - The test suite.
fc7ec1d9 2464
2f381252 2465=head1 PROJECT FOUNDER
2466
2467sri: Sebastian Riedel <sri@cpan.org>
fc7ec1d9 2468
2f381252 2469=head1 CONTRIBUTORS
15f0b5b7 2470
2f381252 2471abw: Andy Wardley
fbcc39ad 2472
2f381252 2473acme: Leon Brocard <leon@astray.com>
33108eaf 2474
f4a57de4 2475Andrew Bramble
2476
15f0b5b7 2477Andrew Ford
2478
2479Andrew Ruthven
2480
2f381252 2481andyg: Andy Grundman <andy@hybridized.org>
fbcc39ad 2482
2f381252 2483audreyt: Audrey Tang
15f0b5b7 2484
2f381252 2485bricas: Brian Cassidy <bricas@cpan.org>
0cf56dbc 2486
2f381252 2487chansen: Christian Hansen
6aaa1c60 2488
2f381252 2489chicks: Christopher Hicks
15f0b5b7 2490
2f381252 2491dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
15f0b5b7 2492
2f381252 2493Drew Taylor
15f0b5b7 2494
2f381252 2495esskar: Sascha Kiefer
0ef52a96 2496
2f381252 2497fireartist: Carl Franks <cfranks@cpan.org>
15f0b5b7 2498
2f381252 2499gabb: Danijel Milicevic
61bef238 2500
15f0b5b7 2501Gary Ashton Jones
2502
2503Geoff Richards
2504
e4cc83b2 2505ilmari: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
2506
2f381252 2507jcamacho: Juan Camacho
fbcc39ad 2508
15f0b5b7 2509Jody Belka
2510
2511Johan Lindstrom
2512
2f381252 2513jon: Jon Schutz <jjschutz@cpan.org>
15f0b5b7 2514
2f381252 2515marcus: Marcus Ramberg <mramberg@cpan.org>
15f0b5b7 2516
2f381252 2517miyagawa: Tatsuhiko Miyagawa <miyagawa@bulknews.net>
15f0b5b7 2518
2f381252 2519mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
15f0b5b7 2520
2f381252 2521mugwump: Sam Vilain
71c3bcc3 2522
2f381252 2523naughton: David Naughton
a727119f 2524
2f381252 2525ningu: David Kamholz <dkamholz@cpan.org>
1cf1c56a 2526
2f381252 2527nothingmuch: Yuval Kogman <nothingmuch@woobling.org>
9c71d51d 2528
2f381252 2529numa: Dan Sully <daniel@cpan.org>
fc7ec1d9 2530
2f381252 2531obra: Jesse Vincent
2532
2533omega: Andreas Marienborg
51f0308d 2534
2f381252 2535phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
bdcb95ef 2536
6dae3eef 2537rafl: Florian Ragwitz <rafl@debian.org>
2538
2f381252 2539sky: Arthur Bergman
2540
2541the_jester: Jesse Sheidlower
2542
2543Ulf Edvinsson
51f0308d 2544
2f381252 2545willert: Sebastian Willert <willert@cpan.org>
51f0308d 2546
fc7ec1d9 2547=head1 LICENSE
2548
9ce5ab63 2549This library is free software, you can redistribute it and/or modify it under
41ca9ba7 2550the same terms as Perl itself.
fc7ec1d9 2551
2552=cut
2553
4090e3bb 2554no Moose;
2555
46d0346d 2556__PACKAGE__->meta->make_immutable;
2557
fc7ec1d9 25581;