X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst.pm;h=7c03083059b3eb48d116ba0172c85f00e4d1b5fb;hb=ffd108e7f870ac00945bfa578389649b39a41b12;hp=4d0031644e6c03320b08b1c5c332fa6520ae84e0;hpb=90de76e8f1edec25c40e4a8666b0b67d14c488e8;p=catagits%2FCatalyst-Runtime.git diff --git a/lib/Catalyst.pm b/lib/Catalyst.pm index 4d00316..7c03083 100644 --- a/lib/Catalyst.pm +++ b/lib/Catalyst.pm @@ -67,7 +67,7 @@ our $GO = Catalyst::Exception::Go->new; #I imagine that very few of these really need to be class variables. if any. #maybe we should just make them attributes with a default? __PACKAGE__->mk_classdata($_) - for qw/components arguments dispatcher engine log dispatcher_class + for qw/container components arguments dispatcher engine log dispatcher_class engine_class context_class request_class response_class stats_class setup_finished/; @@ -79,7 +79,7 @@ __PACKAGE__->stats_class('Catalyst::Stats'); # Remember to update this in Catalyst::Runtime as well! -our $VERSION = '5.80025'; +our $VERSION = '5.80032'; sub import { my ( $class, @arguments ) = @_; @@ -100,7 +100,12 @@ sub import { $meta->superclasses(grep { $_ ne 'Moose::Object' } $meta->superclasses); unless( $meta->has_method('meta') ){ - $meta->add_method(meta => sub { Moose::Meta::Class->initialize("${caller}") } ); + if ($Moose::VERSION >= 1.15) { + $meta->_add_meta_method('meta'); + } + else { + $meta->add_method(meta => sub { Moose::Meta::Class->initialize("${caller}") } ); + } } $caller->arguments( [@arguments] ); @@ -365,6 +370,8 @@ or stash it like so: and access it from the stash. +Keep in mind that the C method used is that of the caller action. So a C<$c-Edetach> inside a forwarded action would run the C method from the original action requested. + =cut sub forward { my $c = shift; no warnings 'recursion'; $c->dispatcher->forward( $c, @_ ) } @@ -745,7 +752,12 @@ sub view { unless ( ref($name) ) { # Direct component hash lookup to avoid costly regexps my $comps = $c->components; my $check = $appclass."::View::".$name; - return $c->_filter_component( $comps->{$check}, @args ) if exists $comps->{$check}; + if( exists $comps->{$check} ) { + return $c->_filter_component( $comps->{$check}, @args ); + } + else { + $c->log->warn( "Attempted to use view '$check', but does not exist" ); + } } my @result = $c->_comp_search_prefixes( $name, qw/View V/ ); return map { $c->_filter_component( $_, @args ) } @result if ref $name; @@ -915,12 +927,18 @@ on the receiving component to access the config value. use Moose; # this attr will receive 'baz' at construction time - has 'bar' => ( + has 'bar' => ( is => 'rw', isa => 'Str', ); You can then get the value 'baz' by calling $c->model('Foo')->bar +(or $self->bar inside code in the model). + +B you MUST NOT call C<< $self->config >> or C<< __PACKAGE__->config >> +as a way of reading config within your code, as this B give you the +correctly merged config back. You B take the config values supplied to +the constructor and use those instead. =cut @@ -1091,6 +1109,7 @@ sub setup { } } + $class->setup_config(); $class->setup_home( delete $flags->{home} ); $class->setup_log( delete $flags->{log} ); @@ -1223,7 +1242,7 @@ EOF A hook to attach modifiers to. This method does not do anything except set the C accessor. -Applying method modifiers to the C method doesn't work, because of quirky thingsdone for plugin setup. +Applying method modifiers to the C method doesn't work, because of quirky things done for plugin setup. Example: @@ -1642,7 +1661,9 @@ sub execute { push( @{ $c->stack }, $code ); no warnings 'recursion'; - eval { $c->state( $code->execute( $class, $c, @{ $c->req->args } ) || 0 ) }; + # N.B. This used to be combined, but I have seen $c get clobbered if so, and + # I have no idea how, ergo $ret (which appears to fix the issue) + eval { my $ret = $code->execute( $class, $c, @{ $c->req->args } ) || 0; $c->state( $ret ) }; $c->_stats_finish_execute( $stats_info ) if $c->use_stats and $stats_info; @@ -1664,8 +1685,8 @@ sub execute { $error = qq/Caught exception in $class->$name "$error"/; } $c->error($error); - $c->state(0); } + $c->state(0); } return $c->state; } @@ -1839,10 +1860,10 @@ sub finalize_headers { } # Content-Length - if ( $response->body && !$response->content_length ) { + if ( defined $response->body && length $response->body && !$response->content_length ) { # get the length from a filehandle - if ( blessed( $response->body ) && $response->body->can('read') ) + if ( blessed( $response->body ) && $response->body->can('read') || ref( $response->body ) eq 'GLOB' ) { my $stat = stat $response->body; if ( $stat && $stat->size > 0 ) { @@ -2344,11 +2365,11 @@ sub prepare_write { my $c = shift; $c->engine->prepare_write( $c, @_ ) } =head2 $c->request_class -Returns or sets the request class. +Returns or sets the request class. Defaults to L. =head2 $c->response_class -Returns or sets the response class. +Returns or sets the response class. Defaults to L. =head2 $c->read( [$maxlength] ) @@ -2391,6 +2412,35 @@ Sets up actions for a component. sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) } +=head2 $c->setup_config + +=cut + +sub setup_config { + my $class = shift; + + my %args = %{$class->config || {} }; + my @container_classes = qw/MyApp::Container Catalyst::Container/; + unshift @container_classes, delete $args{container_class} if exists $args{container_class}; + + my $container_class = Class::MOP::load_first_existing_class(@container_classes); + + my $container = $container_class->new( %args, name => "$class" ); + + $container->add_sub_container(Bread::Board::Container->new( name => $_ )) for qw(model controller view); + $class->container($container); + + my $config = $container->fetch('config')->get; + $class->config($config); + $class->finalize_config; # back-compat +} + +=head $c->finalize_config + +=cut + +sub finalize_config { } + =head2 $c->setup_components This method is called internally to set up the application's components. @@ -2428,8 +2478,18 @@ sub setup_components { Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } ); } + my $containers; + $containers->{$_} = $class->container->get_sub_container($_) for qw(model view controller); + for my $component (@comps) { my $instance = $class->components->{ $component } = $class->setup_component($component); + my $type = lc((split /::/, $component)[1]); + if ($deprecatedcatalyst_component_names) { + $type = 'controller' if $type eq 'c'; + $type = 'model' if $type eq 'm'; + $type = 'view' if $type eq 'v'; + } + $containers->{$type}->add_service(Bread::Board::BlockInjection->new( name => $component, block => sub { return $instance } )); my @expanded_components = $instance->can('expand_modules') ? $instance->expand_modules( $component, $config ) : $class->expand_component_module( $component, $config ); @@ -3206,6 +3266,12 @@ Yuval Kogman, C rainboxx: Matthias Dietrich, C +dd070: Dhaval Dhanani + +=head1 COPYRIGHT + +Copyright (c) 2005, the above named PROJECT FOUNDER and CONTRIBUTORS. + =head1 LICENSE This library is free software. You can redistribute it and/or modify it under