Restartable app class on perl 5.10. More evil hackery..
[catagits/Catalyst-Runtime.git] / lib / Catalyst.pm
index e60e1bb..91239c4 100644 (file)
@@ -2,6 +2,7 @@ package Catalyst;
 
 use Moose;
 extends 'Catalyst::Component';
+use Moose::Util qw/find_meta/;
 use bytes;
 use Scope::Upper ();
 use Catalyst::Exception;
@@ -43,11 +44,9 @@ sub depth { scalar @{ shift->stack || [] }; }
 sub comp { shift->component(@_) }
 
 sub req {
-    # carp "the use of req() is deprecated in favour of request()";
     my $self = shift; return $self->request(@_);
 }
 sub res {
-    # carp "the use of res() is deprecated in favour of response()";
     my $self = shift; return $self->response(@_);
 }
 
@@ -76,7 +75,7 @@ __PACKAGE__->stats_class('Catalyst::Stats');
 
 # Remember to update this in Catalyst::Runtime as well!
 
-our $VERSION = '5.8000_07';
+our $VERSION = '5.80001';
 
 {
     my $dev_version = $VERSION =~ /_\d{2}$/;
@@ -1056,10 +1055,11 @@ EOF
     }
 
     # Call plugins setup, this is stupid and evil.
+    # Also screws C3 badly on 5.10, hack to avoid.
     {
         no warnings qw/redefine/;
         local *setup = sub { };
-        $class->setup;
+        $class->setup unless $Catalyst::__AM_RESTARTING;
     }
 
     # Initialize our data structure
@@ -1482,6 +1482,7 @@ sub execute {
 
     push( @{ $c->stack }, $code );
     
+    no warnings 'recursion';
     eval { $c->state( $code->execute( $class, $c, @{ $c->req->args } ) || 0 ) };
 
     $c->_stats_finish_execute( $stats_info ) if $c->use_stats and $stats_info;
@@ -2162,6 +2163,14 @@ sub setup_components {
 
 =cut
 
+sub _controller_init_base_classes {
+    my ($class, $component) = @_;
+    foreach my $class ( reverse @{ mro::get_linear_isa($component) } ) {
+        Moose->init_meta( for_class => $class )
+            unless find_meta($class);
+    }
+}
+
 sub setup_component {
     my( $class, $component ) = @_;
 
@@ -2169,6 +2178,14 @@ sub setup_component {
         return $component;
     }
 
+    # FIXME - Ugly, ugly hack to ensure the we force initialize non-moose base classes
+    #         nearest to Catalyst::Controller first, no matter what order stuff happens
+    #         to be loaded. There are TODO tests in Moose for this, see
+    #         f2391d17574eff81d911b97be15ea51080500003
+    if ($component->isa('Catalyst::Controller')) {
+        $class->_controller_init_base_classes($component);
+    }
+    
     my $suffix = Catalyst::Utils::class2classsuffix( $component );
     my $config = $class->config->{ $suffix } || {};
 
@@ -2181,11 +2198,16 @@ sub setup_component {
         );
     }
 
-    Catalyst::Exception->throw(
-        message =>
-        qq/Couldn't instantiate component "$component", "COMPONENT() didn't return an object-like value"/
-    ) unless blessed($instance);
-
+    unless (blessed $instance) {
+        my $metaclass = Moose::Util::find_meta($component);
+        my $method_meta = $metaclass->find_method_by_name('COMPONENT');
+        my $component_method_from = $method_meta->associated_metaclass->name;
+        my $value = defined($instance) ? $instance : 'undef';
+        Catalyst::Exception->throw(
+            message =>
+            qq/Couldn't instantiate component "$component", COMPONENT() method (from $component_method_from) didn't return an object-like value (value was $value)./
+        );
+    }
     return $instance;
 }