From: Tomas Doran Date: Tue, 21 Apr 2009 00:27:57 +0000 (+0000) Subject: Fixed non-moose classes initialization order issues. Not quite as fugly as I first... X-Git-Tag: 5.80002~11 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=commitdiff_plain;h=2f5cb0703a06e037f2521ba220242a937d0e35b9 Fixed non-moose classes initialization order issues. Not quite as fugly as I first thought, but still kills kittens --- diff --git a/Changes b/Changes index 8581c86..2e5489c 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,8 @@ # This file documents the revision history for Perl extension Catalyst. + - Work around issues in Moose with initialization order of multiple + levels of non-Moose classes inheriting from a Moose class (t0m) + - Test for this - Add backwards compatibility method for Catalyst::Log->body, which has been made private (t0m) - Fix so that calling $c->req->parameters(undef) does not flatten diff --git a/lib/Catalyst.pm b/lib/Catalyst.pm index 664f0d2..52b7787 100644 --- a/lib/Catalyst.pm +++ b/lib/Catalyst.pm @@ -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; @@ -2161,6 +2162,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 ) = @_; @@ -2168,6 +2177,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 } || {}; diff --git a/t/unit_metaclass_compat_non_moose_controller.t b/t/unit_metaclass_compat_non_moose_controller.t new file mode 100644 index 0000000..d2a61d9 --- /dev/null +++ b/t/unit_metaclass_compat_non_moose_controller.t @@ -0,0 +1,26 @@ +use Catalyst (); + +{ + package TestApp::Controller::Base; + use base qw/Catalyst::Controller/; +} +{ + package TestApp::Controller::Other; + use base qw/TestApp::Controller::Base/; +} + +Catalyst->setup_component('TestApp::Controller::Other'); +Catalyst->setup_component('TestApp::Controller::Base'); + +use Test::More tests => 1; +use Test::Exception; + +# Metaclass init order causes fail. +# There are TODO tests in Moose for this, see +# f2391d17574eff81d911b97be15ea51080500003 +# after which the evil kludge in core can die in a fire. + +lives_ok { + TestApp::Controller::Base->get_action_methods +} 'Base class->get_action_methods ok when sub class initialized first'; +