Merge branch 'master' into gsoc_breadboard gsoc_breadboard
André Walker [Sat, 20 Oct 2012 05:25:28 +0000 (02:25 -0300)]
1  2 
lib/Catalyst.pm
lib/Catalyst/Controller.pm

diff --combined lib/Catalyst.pm
@@@ -15,7 -15,8 +15,7 @@@ use Catalyst::Response
  use Catalyst::Utils;
  use Catalyst::Controller;
  use Data::OptList;
 -use Devel::InnerPackage ();
 -use Module::Pluggable::Object ();
 +use File::stat;
  use Text::SimpleTable ();
  use Path::Class::Dir ();
  use Path::Class::File ();
@@@ -51,20 -52,30 +51,30 @@@ has request => 
      is => 'rw',
      default => sub {
          my $self = shift;
-         my %p = ( _log => $self->log );
-         $p{_uploadtmp} = $self->_uploadtmp if $self->_has_uploadtmp;
-         $self->request_class->new(\%p);
+         $self->request_class->new($self->_build_request_constructor_args);
      },
      lazy => 1,
  );
+ sub _build_request_constructor_args {
+     my $self = shift;
+     my %p = ( _log => $self->log );
+     $p{_uploadtmp} = $self->_uploadtmp if $self->_has_uploadtmp;
+     \%p;
+ }
  has response => (
      is => 'rw',
      default => sub {
          my $self = shift;
-         $self->response_class->new({ _log => $self->log });
+         $self->response_class->new($self->_build_response_constructor_args);
      },
      lazy => 1,
  );
+ sub _build_response_constructor_args {
+     my $self = shift;
+     { _log => $self->log };
+ }
  has namespace => (is => 'rw');
  
  sub depth { scalar @{ shift->stack || [] }; }
@@@ -90,7 -101,7 +100,7 @@@ our $GO        = Catalyst::Exception::G
  #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 arguments dispatcher engine log dispatcher_class
    engine_loader context_class request_class response_class stats_class
    setup_finished _psgi_app loading_psgi_file run_options/;
  
@@@ -101,7 -112,7 +111,7 @@@ __PACKAGE__->stats_class('Catalyst::Sta
  
  # Remember to update this in Catalyst::Runtime as well!
  
- our $VERSION = '5.90016';
+ our $VERSION = '5.90017';
  
  sub import {
      my ( $class, @arguments ) = @_;
      return if $caller eq 'main';
  
      my $meta = Moose::Meta::Class->initialize($caller);
 -    unless ( $caller->isa('Catalyst') ) {
 -        my @superclasses = ($meta->superclasses, $class, 'Catalyst::Controller');
 -        $meta->superclasses(@superclasses);
 -    }
 +
 +    unless ( $caller->isa('Catalyst') ) { # XXX - Remove!
 +        my @superclasses = ($meta->superclasses, $class, 'Catalyst::Component'); # XXX - Remove!
 +        $meta->superclasses(@superclasses); # XXX - Remove!
 +    } # XXX - Remove!
 +
      # Avoid possible C3 issues if 'Moose::Object' is already on RHS of MyApp
      $meta->superclasses(grep { $_ ne 'Moose::Object' } $meta->superclasses);
  
      }
  
      $caller->arguments( [@arguments] );
 +
 +    # FIXME
 +    # what is this for?
 +    # we call setup_home on import AND on ->setup
 +    # is there a reason for it?
 +    # anyway there is no point for setup_home without setup_config() so...
 +    $caller->setup_config;
      $caller->setup_home;
  }
  
 +sub MODIFY_CODE_ATTRIBUTES {
 +    Catalyst::Exception->throw(
 +        "Catalyst applications (aka MyApp) cannot be controllers anymore. " .
 +        "That has been deprecated and removed. You should create a " .
 +        "controller class called Root.pm, and move relevant code to that class."
 +    );
 +}
 +
 +
  sub _application { $_[0] }
  
  =encoding UTF-8
@@@ -546,6 -539,98 +556,6 @@@ sub clear_errors 
      $c->error(0);
  }
  
 -sub _comp_search_prefixes {
 -    my $c = shift;
 -    return map $c->components->{ $_ }, $c->_comp_names_search_prefixes(@_);
 -}
 -
 -# search components given a name and some prefixes
 -sub _comp_names_search_prefixes {
 -    my ( $c, $name, @prefixes ) = @_;
 -    my $appclass = ref $c || $c;
 -    my $filter   = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
 -    $filter = qr/$filter/; # Compile regex now rather than once per loop
 -
 -    # map the original component name to the sub part that we will search against
 -    my %eligible = map { my $n = $_; $n =~ s{^$appclass\::[^:]+::}{}; $_ => $n; }
 -        grep { /$filter/ } keys %{ $c->components };
 -
 -    # undef for a name will return all
 -    return keys %eligible if !defined $name;
 -
 -    my $query  = $name->$_isa('Regexp') ? $name : qr/^$name$/i;
 -    my @result = grep { $eligible{$_} =~ m{$query} } keys %eligible;
 -
 -    return @result if @result;
 -
 -    # if we were given a regexp to search against, we're done.
 -    return if $name->$_isa('Regexp');
 -
 -    # skip regexp fallback if configured
 -    return
 -        if $appclass->config->{disable_component_resolution_regex_fallback};
 -
 -    # regexp fallback
 -    $query  = qr/$name/i;
 -    @result = grep { $eligible{ $_ } =~ m{$query} } keys %eligible;
 -
 -    # no results? try against full names
 -    if( !@result ) {
 -        @result = grep { m{$query} } keys %eligible;
 -    }
 -
 -    # don't warn if we didn't find any results, it just might not exist
 -    if( @result ) {
 -        # Disgusting hack to work out correct method name
 -        my $warn_for = lc $prefixes[0];
 -        my $msg = "Used regexp fallback for \$c->${warn_for}('${name}'), which found '" .
 -           (join '", "', @result) . "'. Relying on regexp fallback behavior for " .
 -           "component resolution is unreliable and unsafe.";
 -        my $short = $result[0];
 -        # remove the component namespace prefix
 -        $short =~ s/.*?(Model|Controller|View):://;
 -        my $shortmess = Carp::shortmess('');
 -        if ($shortmess =~ m#Catalyst/Plugin#) {
 -           $msg .= " You probably need to set '$short' instead of '${name}' in this " .
 -              "plugin's config";
 -        } elsif ($shortmess =~ m#Catalyst/lib/(View|Controller)#) {
 -           $msg .= " You probably need to set '$short' instead of '${name}' in this " .
 -              "component's config";
 -        } else {
 -           $msg .= " You probably meant \$c->${warn_for}('$short') instead of \$c->${warn_for}('${name}'), " .
 -              "but if you really wanted to search, pass in a regexp as the argument " .
 -              "like so: \$c->${warn_for}(qr/${name}/)";
 -        }
 -        $c->log->warn( "${msg}$shortmess" );
 -    }
 -
 -    return @result;
 -}
 -
 -# Find possible names for a prefix
 -sub _comp_names {
 -    my ( $c, @prefixes ) = @_;
 -    my $appclass = ref $c || $c;
 -
 -    my $filter = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
 -
 -    my @names = map { s{$filter}{}; $_; }
 -        $c->_comp_names_search_prefixes( undef, @prefixes );
 -
 -    return @names;
 -}
 -
 -# Filter a component before returning by calling ACCEPT_CONTEXT if available
 -sub _filter_component {
 -    my ( $c, $comp, @args ) = @_;
 -
 -    if ( eval { $comp->can('ACCEPT_CONTEXT'); } ) {
 -        return $comp->ACCEPT_CONTEXT( $c, @args );
 -    }
 -
 -    return $comp;
 -}
 -
  =head2 COMPONENT ACCESSORS
  
  =head2 $c->controller($name)
@@@ -565,7 -650,23 +575,7 @@@ If you want to search for controllers, 
  
  =cut
  
 -sub controller {
 -    my ( $c, $name, @args ) = @_;
 -
 -    my $appclass = ref($c) || $c;
 -    if( $name ) {
 -        unless ( $name->$_isa('Regexp') ) { # Direct component hash lookup to avoid costly regexps
 -            my $comps = $c->components;
 -            my $check = $appclass."::Controller::".$name;
 -            return $c->_filter_component( $comps->{$check}, @args ) if exists $comps->{$check};
 -        }
 -        my @result = $c->_comp_search_prefixes( $name, qw/Controller C/ );
 -        return map { $c->_filter_component( $_, @args ) } @result if ref $name;
 -        return $c->_filter_component( $result[ 0 ], @args );
 -    }
 -
 -    return $c->component( $c->action->class );
 -}
 +sub controller { shift->_lookup_mvc('controller', @_) }
  
  =head2 $c->model($name)
  
@@@ -588,7 -689,42 +598,7 @@@ If you want to search for models, pass 
  
  =cut
  
 -sub model {
 -    my ( $c, $name, @args ) = @_;
 -    my $appclass = ref($c) || $c;
 -    if( $name ) {
 -        unless ( $name->$_isa('Regexp') ) { # Direct component hash lookup to avoid costly regexps
 -            my $comps = $c->components;
 -            my $check = $appclass."::Model::".$name;
 -            return $c->_filter_component( $comps->{$check}, @args ) if exists $comps->{$check};
 -        }
 -        my @result = $c->_comp_search_prefixes( $name, qw/Model M/ );
 -        return map { $c->_filter_component( $_, @args ) } @result if ref $name;
 -        return $c->_filter_component( $result[ 0 ], @args );
 -    }
 -
 -    if (ref $c) {
 -        return $c->stash->{current_model_instance}
 -          if $c->stash->{current_model_instance};
 -        return $c->model( $c->stash->{current_model} )
 -          if $c->stash->{current_model};
 -    }
 -    return $c->model( $appclass->config->{default_model} )
 -      if $appclass->config->{default_model};
 -
 -    my( $comp, $rest ) = $c->_comp_search_prefixes( undef, qw/Model M/);
 -
 -    if( $rest ) {
 -        $c->log->warn( Carp::shortmess('Calling $c->model() will return a random model unless you specify one of:') );
 -        $c->log->warn( '* $c->config(default_model => "the name of the default model to use")' );
 -        $c->log->warn( '* $c->stash->{current_model} # the name of the model to use for this request' );
 -        $c->log->warn( '* $c->stash->{current_model_instance} # the instance of the model to use for this request' );
 -        $c->log->warn( 'NB: in version 5.81, the "random" behavior will not work at all.' );
 -    }
 -
 -    return $c->_filter_component( $comp );
 -}
 -
 +sub model { shift->_lookup_mvc('model', @_) }
  
  =head2 $c->view($name)
  
@@@ -611,23 -747,46 +621,23 @@@ If you want to search for views, pass i
  
  =cut
  
 -sub view {
 -    my ( $c, $name, @args ) = @_;
 +sub view { shift->_lookup_mvc('view', @_) }
  
 -    my $appclass = ref($c) || $c;
 -    if( $name ) {
 -        unless ( $name->$_isa('Regexp') ) { # Direct component hash lookup to avoid costly regexps
 -            my $comps = $c->components;
 -            my $check = $appclass."::View::".$name;
 -            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;
 -        return $c->_filter_component( $result[ 0 ], @args );
 -    }
 +sub _lookup_mvc {
 +    my ( $c, $type, $name, @args ) = @_;
  
 -    if (ref $c) {
 -        return $c->stash->{current_view_instance}
 -          if $c->stash->{current_view_instance};
 -        return $c->view( $c->stash->{current_view} )
 -          if $c->stash->{current_view};
 -    }
 -    return $c->view( $appclass->config->{default_view} )
 -      if $appclass->config->{default_view};
 +    if (ref $c && !$name) {
 +        my $current_instance = $c->stash->{"current_${type}_instance"};
 +        return $current_instance
 +            if $current_instance && $type ne 'controller';
  
 -    my( $comp, $rest ) = $c->_comp_search_prefixes( undef, qw/View V/);
 -
 -    if( $rest ) {
 -        $c->log->warn( 'Calling $c->view() will return a random view unless you specify one of:' );
 -        $c->log->warn( '* $c->config(default_view => "the name of the default view to use")' );
 -        $c->log->warn( '* $c->stash->{current_view} # the name of the view to use for this request' );
 -        $c->log->warn( '* $c->stash->{current_view_instance} # the instance of the view to use for this request' );
 -        $c->log->warn( 'NB: in version 5.81, the "random" behavior will not work at all.' );
 +        $name = $type eq 'controller'
 +              ? Catalyst::Utils::class2classshortsuffix($c->action->class)
 +              : $c->stash->{"current_${type}"}
 +              ;
      }
  
 -    return $c->_filter_component( $comp );
 +    return $c->container->get_component_from_sub_container($type, $name, $c, @args);
  }
  
  =head2 $c->controllers
@@@ -638,7 -797,7 +648,7 @@@ Returns the available names which can b
  
  sub controllers {
      my ( $c ) = @_;
 -    return $c->_comp_names(qw/Controller C/);
 +    return $c->container->get_sub_container('controller')->get_service_list;
  }
  
  =head2 $c->models
@@@ -649,7 -808,7 +659,7 @@@ Returns the available names which can b
  
  sub models {
      my ( $c ) = @_;
 -    return $c->_comp_names(qw/Model M/);
 +    return $c->container->get_sub_container('model')->get_service_list;
  }
  
  
@@@ -661,7 -820,7 +671,7 @@@ Returns the available names which can b
  
  sub views {
      my ( $c ) = @_;
 -    return $c->_comp_names(qw/View V/);
 +    return $c->container->get_sub_container('view')->get_service_list;
  }
  
  =head2 $c->comp($name)
@@@ -676,50 -835,57 +686,50 @@@ should be used instead
  If C<$name> is a regexp, a list of components matched against the full
  component name will be returned.
  
  =cut
  
  sub component {
 -    my ( $c, $name, @args ) = @_;
 +    my ( $c, $component, @args ) = @_;
  
 -    if( $name ) {
 -        my $comps = $c->components;
 +    unless ($component) {
 +        $c->log->warn('Calling $c->component with no args is deprecated and ');
 +        $c->log->warn('will be removed in a future release.');
 +        $c->log->warn('Use $c->component_list instead.');
 +        return $c->component_list;
 +    }
  
 -        if( !ref $name ) {
 -            # is it the exact name?
 -            return $c->_filter_component( $comps->{ $name }, @args )
 -                       if exists $comps->{ $name };
 +    my @result = $c->container->find_component( $component, $c, @args );
  
 -            # perhaps we just omitted "MyApp"?
 -            my $composed = ( ref $c || $c ) . "::${name}";
 -            return $c->_filter_component( $comps->{ $composed }, @args )
 -                       if exists $comps->{ $composed };
 +    # list context for regexp searches
 +    return @result if ref $component;
  
 -            # search all of the models, views and controllers
 -            my( $comp ) = $c->_comp_search_prefixes( $name, qw/Model M Controller C View V/ );
 -            return $c->_filter_component( $comp, @args ) if $comp;
 -        }
 +    # only one component (if it's found) for string searches
 +    return shift @result if @result;
  
 -        return
 -            if $c->config->{disable_component_resolution_regex_fallback};
 +    if (ref $c eq $component) {
 +        $c->log->warn('You are calling $c->comp("MyApp"). This behaviour is');
 +        $c->log->warn('deprecated, and will be removed in a future release.');
 +        return $c;
 +    }
  
 -        # This is here so $c->comp( '::M::' ) works
 -        my $query = ref $name ? $name : qr{$name}i;
 +    $c->log->warn("Looking for '$component', but nothing was found.");
  
 -        my @result = grep { m{$query} } keys %{ $c->components };
 -        return map { $c->_filter_component( $_, @args ) } @result if ref $name;
 +    # I would expect to return an empty list here, but that breaks back-compat
 +    $c->log->warn('Component not found, returning the list of existing');
 +    $c->log->warn('components. This behavior is deprecated and will be');
 +    $c->log->warn('removed in a future release. Use $c->component_list');
 +    $c->log->warn('instead.');
  
 -        if( $result[ 0 ] ) {
 -            $c->log->warn( Carp::shortmess(qq(Found results for "${name}" using regexp fallback)) );
 -            $c->log->warn( 'Relying on the regexp fallback behavior for component resolution' );
 -            $c->log->warn( 'is unreliable and unsafe. You have been warned' );
 -            return $c->_filter_component( $result[ 0 ], @args );
 -        }
 +    return $c->component_list;
 +}
  
 -        # I would expect to return an empty list here, but that breaks back-compat
 -    }
 +=head2 $c->component_list
  
 -    # fallback
 -    return sort keys %{ $c->components };
 -}
 +Returns the sorted list of the component names of the application.
 +
 +=cut
 +
 +sub component_list { sort keys %{ shift->components } }
  
  =head2 CLASS DATA AND HELPER CLASSES
  
@@@ -870,7 -1036,6 +880,7 @@@ sub path_to 
  sub plugin {
      my ( $class, $name, $plugin, @args ) = @_;
  
 +    # See block comment in t/aggregate/unit_core_plugin.t
      # See block comment in t/unit_core_plugin.t
      $class->log->warn(qq/Adding plugin using the ->plugin method is deprecated, and will be removed in a future release/);
  
@@@ -938,7 -1103,6 +948,7 @@@ sub setup 
          }
      }
  
 +    $class->setup_config();
      $class->setup_home( delete $flags->{home} );
  
      $class->setup_log( delete $flags->{log} );
          $class->setup unless $Catalyst::__AM_RESTARTING;
      }
  
 -    # Initialize our data structure
 -    $class->components( {} );
 -
      $class->setup_components;
  
 -    if ( $class->debug ) {
 +    if (
 +        $class->debug and
 +        my $comps = $class->container->get_all_components($class)
 +    ) {
          my $column_width = Catalyst::Utils::term_width() - 8 - 9;
          my $t = Text::SimpleTable->new( [ $column_width, '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 . "\n" )
 -          if ( keys %{ $class->components } );
 -    }
 +        $t->row( $_ => ref($comps->{$_}) ? 'instance' : 'class' ) for keys %$comps;
  
 -    # Add our self to components, since we are also a component
 -    if( $class->isa('Catalyst::Controller') ){
 -      $class->components->{$class} = $class;
 +        $class->log->debug( "Loaded components:\n" . $t->draw . "\n" );
      }
  
      $class->setup_actions;
@@@ -1434,23 -1606,6 +1444,23 @@@ These methods are not meant to be used 
  
  Returns a hash of components.
  
 +=cut
 +
 +sub components {
 +    my ( $class, $comps ) = @_;
 +
 +    # people create components calling this sub directly, before setup
 +    $class->setup_config unless $class->container;
 +
 +    my $container = $class->container;
 +
 +    if ( $comps ) {
 +        $container->add_component( $_ ) for keys %$comps;
 +    }
 +
 +    return $container->get_all_components($class);
 +}
 +
  =head2 $c->context_class
  
  Returns or sets the context class.
@@@ -2329,67 -2484,137 +2339,67 @@@ Sets up actions for a component
  
  sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
  
 -=head2 $c->setup_components
 -
 -This method is called internally to set up the application's components.
 -
 -It finds modules by calling the L<locate_components> method, expands them to
 -package names with the L<expand_component_module> method, and then installs
 -each component into the application.
 -
 -The C<setup_components> config option is passed to both of the above methods.
 -
 -Installation of each component is performed by the L<setup_component> method,
 -below.
 +=head2 $c->setup_config
  
  =cut
  
 -sub setup_components {
 +sub setup_config {
      my $class = shift;
  
 -    my $config  = $class->config->{ setup_components };
 -
 -    my @comps = $class->locate_components($config);
 -    my %comps = map { $_ => 1 } @comps;
 +    my %args = %{ $class->config || {} };
  
 -    my $deprecatedcatalyst_component_names = grep { /::[CMV]::/ } @comps;
 -    $class->log->warn(qq{Your application is using the deprecated ::[MVC]:: type naming scheme.\n}.
 -        qq{Please switch your class names to ::Model::, ::View:: and ::Controller: as appropriate.\n}
 -    ) if $deprecatedcatalyst_component_names;
 +    my $container_class;
  
 -    for my $component ( @comps ) {
 -
 -        # We pass ignore_loaded here so that overlay files for (e.g.)
 -        # Model::DBI::Schema sub-classes are loaded - if it's in @comps
 -        # we know M::P::O found a file on disk so this is safe
 -
 -        Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
 +    if ( exists $args{container_class} ) {
 +        $container_class = delete $args{container_class};
 +        Class::MOP::load_class($container_class);
      }
 -
 -    for my $component (@comps) {
 -        my $instance = $class->components->{ $component } = $class->setup_component($component);
 -        my @expanded_components = $instance->can('expand_modules')
 -            ? $instance->expand_modules( $component, $config )
 -            : $class->expand_component_module( $component, $config );
 -        for my $component (@expanded_components) {
 -            next if $comps{$component};
 -            $class->components->{ $component } = $class->setup_component($component);
 -        }
 +    else {
 +        $container_class = Class::MOP::load_first_existing_class("${class}::Container", 'Catalyst::IOC::Container');
      }
 -}
  
 -=head2 $c->locate_components( $setup_component_config )
 +    my $container = $container_class->new( %args, name => $class );
 +    $class->container($container);
  
 -This method is meant to provide a list of component modules that should be
 -setup for the application.  By default, it will use L<Module::Pluggable>.
 +    my $config = $container->resolve( service => 'config' );
 +    $class->config($config);
 +    $class->finalize_config; # back-compat
 +}
  
 -Specify a C<setup_components> config option to pass additional options directly
 -to L<Module::Pluggable>. To add additional search paths, specify a key named
 -C<search_extra> as an array reference. Items in the array beginning with C<::>
 -will have the application class name prepended to them.
 +=head2 $c->finalize_config
  
  =cut
  
 -sub locate_components {
 -    my $class  = shift;
 -    my $config = shift;
 -
 -    my @paths   = qw( ::Controller ::C ::Model ::M ::View ::V );
 -    my $extra   = delete $config->{ search_extra } || [];
 -
 -    push @paths, @$extra;
 -
 -    my $locator = Module::Pluggable::Object->new(
 -        search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
 -        %$config
 -    );
 +sub finalize_config { }
  
 -    # XXX think about ditching this sort entirely
 -    my @comps = sort { length $a <=> length $b } $locator->plugins;
 +=head2 $c->setup_components
  
 -    return @comps;
 -}
 +This method is called internally to set up the application's components.
  
 -=head2 $c->expand_component_module( $component, $setup_component_config )
 +It finds modules by calling the L<locate_components> method, expands them to
 +package names with the $container->expand_component_module method, and then
 +installs each component into the application.
  
 -Components found by C<locate_components> will be passed to this method, which
 -is expected to return a list of component (package) names to be set up.
 +The C<setup_components> config option is passed to both of the above methods.
  
  =cut
  
 -sub expand_component_module {
 -    my ($class, $module) = @_;
 -    return Devel::InnerPackage::list_packages( $module );
 -}
 +sub setup_components { shift->container->setup_components }
  
 -=head2 $c->setup_component
 +=head2 locate_components
  
  =cut
  
 -sub setup_component {
 -    my( $class, $component ) = @_;
 -
 -    unless ( $component->can( 'COMPONENT' ) ) {
 -        return $component;
 -    }
 -
 -    my $suffix = Catalyst::Utils::class2classsuffix( $component );
 -    my $config = $class->config->{ $suffix } || {};
 -    # Stash catalyst_component_name in the config here, so that custom COMPONENT
 -    # methods also pass it. local to avoid pointlessly shitting in config
 -    # for the debug screen, as $component is already the key name.
 -    local $config->{catalyst_component_name} = $component;
 -
 -    my $instance = eval { $component->COMPONENT( $class, $config ); };
 +sub locate_components {
 +    my $class = shift;
  
 -    if ( my $error = $@ ) {
 -        chomp $error;
 -        Catalyst::Exception->throw(
 -            message => qq/Couldn't instantiate component "$component", "$error"/
 -        );
 -    }
 +    $class->log->warn('The locate_components method has been deprecated.');
 +    $class->log->warn('Please read Catalyst::IOC::Container documentation to');
 +    $class->log->warn('update your application.');
  
 -    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;
 +    # XXX think about ditching this sort entirely
 +    return sort { length $a <=> length $b }
 +        @{ $class->container->resolve( service => 'locate_components' ) };
  }
  
  =head2 $c->setup_dispatcher
@@@ -2618,19 -2843,18 +2628,19 @@@ Sets up the home directory
  =cut
  
  sub setup_home {
 -    my ( $class, $home ) = @_;
 -
 -    if ( my $env = Catalyst::Utils::env_value( $class, 'HOME' ) ) {
 -        $home = $env;
 -    }
 +    my ( $class, $home_flag ) = @_;
  
 -    $home ||= Catalyst::Utils::home($class);
 +    my $home = $class->container->resolve(
 +        service    => 'home',
 +        parameters => {
 +            home_flag => $home_flag
 +        },
 +    );
  
      if ($home) {
          #I remember recently being scolded for assigning config values like this
          $class->config->{home} ||= $home;
 -        $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
 +        $class->config->{root} ||= $class->container->resolve(service => 'root_dir');
      }
  }
  
@@@ -2853,6 -3077,14 +2863,6 @@@ C<default_view> - The default view to b
  
  =item *
  
 -C<disable_component_resolution_regex_fallback> - Turns
 -off the deprecated component resolution functionality so
 -that if any of the component methods (e.g. C<< $c->controller('Foo') >>)
 -are called then regex search will not be attempted on string values and
 -instead C<undef> will be returned.
 -
 -=item *
 -
  C<home> - The application home directory. In an uninstalled application,
  this is the top level application directory. In an installed application,
  this will be the directory containing C<< MyApp.pm >>.
@@@ -2880,6 -3112,12 +2890,6 @@@ templates to a different directory
  
  =item *
  
 -C<search_extra> - Array reference passed to Module::Pluggable to for additional
 -namespaces from which components will be loaded (and constructed and stored in
 -C<< $c->components >>).
 -
 -=item *
 -
  C<show_internal_actions> - If true, causes internal actions such as C<< _DISPATCH >>
  to be shown in hit debug tables in the test server.
  
@@@ -3077,8 -3315,6 +3087,8 @@@ Andrew Ford E<lt>A.Ford@ford-mason.co.u
  
  Andrew Ruthven
  
 +AndrĂ© Walker
 +
  andyg: Andy Grundman <andy@hybridized.org>
  
  audreyt: Audrey Tang
@@@ -187,12 -187,6 +187,12 @@@ around action_namespace => sub 
  
      my $class = ref($self) || $self;
      my $appclass = ref($c) || $c;
 +
 +    # FIXME - catalyst_component_name is no longer a class accessor, because
 +    # 'MyApp as a controller' behavior is removed. But is this call to
 +    # catalyst_component_name necessary, or is it always the same as $class?
 +    my $component_name = ref($self) ? $self->catalyst_component_name : $self;
 +
      if( ref($self) ){
          return $self->$orig if $self->has_action_namespace;
      } else {
          }
      }
  
 -    my $namespace = Catalyst::Utils::class2prefix($self->catalyst_component_name, $case_s) || '';
 +    my $namespace = Catalyst::Utils::class2prefix($component_name, $case_s) || '';
      $self->$orig($namespace) if ref($self);
      return $namespace;
  };
@@@ -281,7 -275,7 +281,7 @@@ sub register_action_methods 
          my $attributes = $method->can('attributes') ? $method->attributes : [];
          my $attrs = $self->_parse_attrs( $c, $name, @{ $attributes } );
          if ( $attrs->{Private} && ( keys %$attrs > 1 ) ) {
-             $c->log->debug( 'Bad action definition "'
+             $c->log->warn( 'Bad action definition "'
                    . join( ' ', @{ $attributes } )
                    . qq/" for "$class->$name"/ )
                if $c->debug;