X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst.pm;h=963c8193400ba64892b1ab519a488851039c617f;hb=e7f1cf73b4e0e5863e901aaa0e6bda2e39bd0edc;hp=2427601c595f371f6510f70453f90d401d848e6c;hpb=1cf1c56a0c68611a361dbb8c797891baf6d0974f;p=catagits%2FCatalyst-Runtime.git diff --git a/lib/Catalyst.pm b/lib/Catalyst.pm index 2427601..963c819 100644 --- a/lib/Catalyst.pm +++ b/lib/Catalyst.pm @@ -16,11 +16,16 @@ use Path::Class; use Time::HiRes qw/gettimeofday tv_interval/; use URI; use Scalar::Util qw/weaken/; +use attributes; __PACKAGE__->mk_accessors( - qw/counter depth request response state action namespace/ + qw/counter request response state action stack namespace/ ); +attributes->import( __PACKAGE__, \&namespace, 'lvalue' ); + +sub depth { scalar @{ shift->stack || [] }; } + # Laziness++ *comp = \&component; *req = \&request; @@ -38,12 +43,18 @@ our $DETACH = "catalyst_detach\n"; require Module::Pluggable::Fast; # Helper script generation -our $CATALYST_SCRIPT_GEN = 10; +our $CATALYST_SCRIPT_GEN = 11; __PACKAGE__->mk_classdata($_) - for qw/components arguments dispatcher engine log/; + for qw/components arguments dispatcher engine log dispatcher_class + engine_class context_class request_class response_class/; -our $VERSION = '5.49_03'; +__PACKAGE__->dispatcher_class('Catalyst::Dispatcher'); +__PACKAGE__->engine_class('Catalyst::Engine::CGI'); +__PACKAGE__->request_class('Catalyst::Request'); +__PACKAGE__->response_class('Catalyst::Response'); + +our $VERSION = '5.49_04'; sub import { my ( $class, @arguments ) = @_; @@ -78,7 +89,7 @@ Catalyst - The Elegant MVC Web Application Framework script/myapp_create.pl view Stuff script/myapp_create.pl controller Yada - # built in testserver + # built in testserver -- use -r to restart automatically on changes script/myapp_server.pl # command line interface @@ -144,10 +155,6 @@ this is equivalent to: use Catalyst; sub debug { 1 } -=item -Dispatcher - -Force Catalyst to use a specific dispatcher. - =item -Engine Force Catalyst to use a specific engine. @@ -171,7 +178,8 @@ Specify log level. =item $c->action -Accessor for the current action +Accessor for the current action. Returns a L object, +which stringifies to the action name. =item $c->comp($name) @@ -254,15 +262,14 @@ sub detach { my $c = shift; $c->dispatcher->detach( $c, @_ ) } =item $c->dispatcher -Contains the dispatcher instance. -Stringifies to class. +Contains the dispatcher instance. Stringifies to class name. =item $c->forward( $command [, \@arguments ] ) Forward processing to a private action or a method from a class. If you define a class without method it will default to process(). also takes an optional arrayref containing arguments to be passed -to the new function. $c->req->args will be reset upon returning +to the new function. $c->req->args will be restored upon returning from the function. $c->forward('/foo'); @@ -291,7 +298,8 @@ sub model { =item $c->namespace -Accessor to the namespace of the current action +Returns the namespace of the current action, i.e., the uri prefix corresponding to the +controller of the current action. =item $c->path_to(@path) @@ -312,7 +320,8 @@ sub path_to { =item $c->setup -Setup. +Initializes the dispatcher and engine, loads any plugins, and loads the +model, view, and controller components. $c->setup; @@ -364,11 +373,13 @@ sub setup { } } - $class->log->warn( "You are running an old helper script! " - . "Please update your scripts by regenerating the " - . "application and copying over the new scripts." ) - if ( $ENV{CATALYST_SCRIPT_GEN} - && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::CATALYST_SCRIPT_GEN ) ); + $class->log->warn( + <<"EOF") if ( $ENV{CATALYST_SCRIPT_GEN} && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::CATALYST_SCRIPT_GEN ) ); +You are running an old script! + + Please update by running: + catalyst.pl -nonew -scripts $class +EOF if ( $class->debug ) { @@ -412,8 +423,11 @@ sub setup { $class->setup_components; if ( $class->debug ) { - my $t = Text::SimpleTable->new(76); - $t->row($_) for sort keys %{ $class->components }; + my $t = Text::SimpleTable->new( [ 65, 'Class' ], [ 8, 'Type' ] ); + for my $comp ( sort keys %{ $class->components } ) { + my $type = ref $class->components->{$comp} ? 'instance' : 'class'; + $t->row( $comp, $type ); + } $class->log->debug( "Loaded components:\n" . $t->draw ) if ( keys %{ $class->components } ); } @@ -474,7 +488,7 @@ Add a new error. $c->error('Something bad happened'); -Clean errors. +Clear errors. $c->error(0); @@ -492,18 +506,17 @@ sub error { =item $c->engine -Contains the engine instance. -Stringifies to the class. +Contains the engine instance. Stringifies to the class name. =item $c->log Contains the logging object. Unless it is already set Catalyst sets this up with a -C object. To use your own log class: +L object. To use your own log class: $c->log( MyLogger->new ); $c->log->info("now logging with my own logger!"); -Your log class should implement the methods described in the C +Your log class should implement the methods described in the L man page. =item $c->plugin( $name, $class, @args ) @@ -775,25 +788,32 @@ sub benchmark { =item $c->components -Contains the components. +Returns a hash of components. + +=item $c->context_class + +Returns or sets the context class. =item $c->counter -Returns a hashref containing coderefs and execution counts. -(Needed for deep recursion detection) +Returns a hashref containing coderefs and execution counts (needed for deep recursion detection). =item $c->depth -Returns the actual forward depth. +Returns the number of actions on the current internal execution stack. =item $c->dispatch -Dispatch request to actions. +Dispatches a request to actions. =cut sub dispatch { my $c = shift; $c->dispatcher->dispatch( $c, @_ ) } +=item $c->dispatcher_class + +Returns or sets the dispatcher class. + =item dump_these Returns a list of 2-element array references (name, structure) pairs that will @@ -806,6 +826,10 @@ sub dump_these { [ Request => $c->req ], [ Response => $c->res ], [ Stash => $c->stash ],; } +=item $c->engine_class + +Returns or sets the engine class. + =item $c->execute($class, $coderef) Execute a coderef in given class and catch exceptions. @@ -817,7 +841,11 @@ sub execute { my ( $c, $class, $code ) = @_; $class = $c->components->{$class} || $class; $c->state(0); - my $callsub = ( caller(1) )[3]; + + my $callsub = + ( caller(0) )[0]->isa('Catalyst::Action') + ? ( caller(2) )[3] + : ( caller(1) )[3]; my $action = ''; if ( $c->debug ) { @@ -835,7 +863,7 @@ sub execute { $action = "-> $action" if $callsub =~ /forward$/; } - $c->{depth}++; + push( @{ $c->stack }, $code ); eval { if ( $c->debug ) { @@ -852,11 +880,11 @@ sub execute { $c->state( &$code( $class, $c, @{ $c->req->args } ) || 0 ); } }; - $c->{depth}--; + pop( @{ $c->stack } ); if ( my $error = $@ ) { - if ( $error eq $DETACH ) { die $DETACH if $c->{depth} > 1 } + if ( $error eq $DETACH ) { die $DETACH if $c->depth > 1 } else { unless ( ref $error ) { chomp $error; @@ -871,7 +899,7 @@ sub execute { =item $c->finalize -Finalize request. +Finalizes the request. =cut @@ -903,7 +931,7 @@ sub finalize { =item $c->finalize_body -Finalize body. +Finalizes body. =cut @@ -911,7 +939,7 @@ sub finalize_body { my $c = shift; $c->engine->finalize_body( $c, @_ ) } =item $c->finalize_cookies -Finalize cookies. +Finalizes cookies. =cut @@ -919,7 +947,7 @@ sub finalize_cookies { my $c = shift; $c->engine->finalize_cookies( $c, @_ ) } =item $c->finalize_error -Finalize error. +Finalizes error. =cut @@ -927,7 +955,7 @@ sub finalize_error { my $c = shift; $c->engine->finalize_error( $c, @_ ) } =item $c->finalize_headers -Finalize headers. +Finalizes headers. =cut @@ -968,7 +996,7 @@ An alias for finalize_body. =item $c->finalize_read -Finalize the input after reading is complete. +Finalizes the input after reading is complete. =cut @@ -976,7 +1004,7 @@ sub finalize_read { my $c = shift; $c->engine->finalize_read( $c, @_ ) } =item $c->finalize_uploads -Finalize uploads. Cleans up any temporary files. +Finalizes uploads. Cleans up any temporary files. =cut @@ -984,15 +1012,15 @@ sub finalize_uploads { my $c = shift; $c->engine->finalize_uploads( $c, @_ ) } =item $c->get_action( $action, $namespace ) -Get an action in a given namespace. +Gets an action in a given namespace. =cut -sub get_action { my $c = shift; $c->dispatcher->get_action( $c, @_ ) } +sub get_action { my $c = shift; $c->dispatcher->get_action(@_) } =item $c->get_actions( $action, $namespace ) -Get all actions of a given name in a namespace and all base namespaces. +Gets all actions of a given name in a namespace and all parent namespaces. =cut @@ -1000,7 +1028,7 @@ sub get_actions { my $c = shift; $c->dispatcher->get_actions( $c, @_ ) } =item handle_request( $class, @arguments ) -Handles the request. +Called to handle each HTTP request. =cut @@ -1047,41 +1075,43 @@ sub handle_request { =item $c->prepare(@arguments) -Turns the engine-specific request( Apache, CGI ... ) -into a Catalyst context . +Creates a Catalyst context from an engine-specific request (Apache, CGI, etc.). =cut sub prepare { my ( $class, @arguments ) = @_; - my $c = bless { - counter => {}, - depth => 0, - request => Catalyst::Request->new( - { - arguments => [], - body_parameters => {}, - cookies => {}, - headers => HTTP::Headers->new, - parameters => {}, - query_parameters => {}, - secure => 0, - snippets => [], - uploads => {} - } - ), - response => Catalyst::Response->new( - { - body => '', - cookies => {}, - headers => HTTP::Headers->new(), - status => 200 - } - ), - stash => {}, - state => 0 - }, $class; + $class->context_class( ref $class || $class ) unless $class->context_class; + my $c = $class->context_class->new( + { + counter => {}, + stack => [], + request => $class->request_class->new( + { + arguments => [], + body_parameters => {}, + cookies => {}, + headers => HTTP::Headers->new, + parameters => {}, + query_parameters => {}, + secure => 0, + snippets => [], + uploads => {} + } + ), + response => $class->response_class->new( + { + body => '', + cookies => {}, + headers => HTTP::Headers->new(), + status => 200 + } + ), + stash => {}, + state => 0 + } + ); # For on-demand data $c->request->{_context} = $c; @@ -1121,7 +1151,7 @@ sub prepare { =item $c->prepare_action -Prepare action. +Prepares action. =cut @@ -1129,7 +1159,7 @@ sub prepare_action { my $c = shift; $c->dispatcher->prepare_action( $c, @_ ) } =item $c->prepare_body -Prepare message body. +Prepares message body. =cut @@ -1158,7 +1188,7 @@ sub prepare_body { =item $c->prepare_body_chunk( $chunk ) -Prepare a chunk of data before sending it to HTTP::Body. +Prepares a chunk of data before sending it to L. =cut @@ -1169,7 +1199,7 @@ sub prepare_body_chunk { =item $c->prepare_body_parameters -Prepare body parameters. +Prepares body parameters. =cut @@ -1180,7 +1210,7 @@ sub prepare_body_parameters { =item $c->prepare_connection -Prepare connection. +Prepares connection. =cut @@ -1191,7 +1221,7 @@ sub prepare_connection { =item $c->prepare_cookies -Prepare cookies. +Prepares cookies. =cut @@ -1199,7 +1229,7 @@ sub prepare_cookies { my $c = shift; $c->engine->prepare_cookies( $c, @_ ) } =item $c->prepare_headers -Prepare headers. +Prepares headers. =cut @@ -1207,7 +1237,7 @@ sub prepare_headers { my $c = shift; $c->engine->prepare_headers( $c, @_ ) } =item $c->prepare_parameters -Prepare parameters. +Prepares parameters. =cut @@ -1219,7 +1249,7 @@ sub prepare_parameters { =item $c->prepare_path -Prepare path and base. +Prepares path and base. =cut @@ -1227,7 +1257,7 @@ sub prepare_path { my $c = shift; $c->engine->prepare_path( $c, @_ ) } =item $c->prepare_query_parameters -Prepare query parameters. +Prepares query parameters. =cut @@ -1250,7 +1280,7 @@ sub prepare_query_parameters { =item $c->prepare_read -Prepare the input for reading. +Prepares the input for reading. =cut @@ -1258,7 +1288,7 @@ sub prepare_read { my $c = shift; $c->engine->prepare_read( $c, @_ ) } =item $c->prepare_request -Prepare the engine request. +Prepares the engine request. =cut @@ -1266,7 +1296,7 @@ sub prepare_request { my $c = shift; $c->engine->prepare_request( $c, @_ ) } =item $c->prepare_uploads -Prepare uploads. +Prepares uploads. =cut @@ -1294,15 +1324,23 @@ sub prepare_uploads { =item $c->prepare_write -Prepare the output for writing. +Prepares the output for writing. =cut sub prepare_write { my $c = shift; $c->engine->prepare_write( $c, @_ ) } +=item $c->request_class + +Returns or sets the request class. + +=item $c->response_class + +Returns or sets the response class. + =item $c->read( [$maxlength] ) -Read a chunk of data from the request body. This method is designed to be +Reads a chunk of data from the request body. This method is designed to be used in a while loop, reading $maxlength bytes on every call. $maxlength defaults to the size of the request if not specified. @@ -1322,7 +1360,7 @@ sub run { my $c = shift; return $c->engine->run( $c, @_ ) } =item $c->set_action( $action, $code, $namespace, $attrs ) -Set an action in a given namespace. +Sets an action in a given namespace. =cut @@ -1330,7 +1368,7 @@ sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) } =item $c->setup_actions($component) -Setup actions for a component. +Sets up actions for a component. =cut @@ -1338,7 +1376,7 @@ sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) } =item $c->setup_components -Setup components. +Sets up components. =cut @@ -1352,7 +1390,7 @@ sub setup_components { return $component; } - my $suffix = Catalyst::Utils::class2classsuffix($class); + my $suffix = Catalyst::Utils::class2classsuffix($component); my $config = $class->config->{$suffix} || {}; my $instance; @@ -1420,7 +1458,7 @@ sub setup_dispatcher { } unless ($dispatcher) { - $dispatcher = 'Catalyst::Dispatcher'; + $dispatcher = $class->dispatcher_class; } $dispatcher->require; @@ -1509,7 +1547,7 @@ sub setup_engine { } unless ($engine) { - $engine = 'Catalyst::Engine::CGI'; + $engine = $class->engine_class; } $engine->require; @@ -1632,6 +1670,10 @@ sub setup_plugins { } } +=item $c->stack + +Contains the stack. + =item $c->write( $data ) Writes $data to the output stream. When using this method directly, you will @@ -1651,7 +1693,7 @@ sub write { =item version -Returns the Catalyst version number. mostly useful for powered by messages +Returns the Catalyst version number. Mostly useful for "powered by" messages in template systems. =cut @@ -1751,6 +1793,8 @@ Web: =item L - The Catalyst Manual +=item L, L - Base classes for components + =item L - Core Engine =item L - The Log Class. @@ -1781,6 +1825,8 @@ Arthur Bergman Autrijus Tang +Brian Cassidy + Christian Hansen Christopher Hicks