If C<$name> is a regexp, a list of components matched against the full
component name will be returned.
-If Catalyst can't find a component by name, it will fallback to regex
-matching by default. To disable this behaviour set
-disable_component_resolution_regex_fallback to a true value.
-
- __PACKAGE__->config( disable_component_resolution_regex_fallback => 1 );
-
=cut
sub component {
my ( $c, $component, @args ) = @_;
- unshift @args, $c;
if ( $component ) {
+ # FIXME: I probably shouldn't be doing this
+ return $c->components->{$component}
+ if exists $c->components->{$component};
+
my ($type, $name) = _get_component_type_name($component);
if ($type && $c->container->has_sub_container($type)) {
my $container = $c->container->get_sub_container($type);
if( !ref $component && $container->has_service($name) ) {
- return $container->get_component( $name, \@args );
+ return $container->get_component( $name, $c, @args );
}
- return $container->get_component_regexp( $c, $name, \@args );
+ return $container->get_component_regexp( $name, $c, @args );
}
- return
- if $c->config->{disable_component_resolution_regex_fallback} && !ref $component;
-
- # This is here so $c->comp( '::M::' ) works
- my $query = ref $component ? $component : qr{$component}i;
-
- for my $subcontainer_name (qw/model view controller/) {
- my $subcontainer = $c->container->get_sub_container($subcontainer_name);
- my @components = $subcontainer->get_service_list;
- my @result = grep { m{$query} } @components;
-
- if (@result) {
- return map { $subcontainer->get_component( $_, \@args ) } @result
- if ref $component;
+ if (ref $component) {
+ for my $subcontainer_name (qw/model view controller/) {
+ my $subcontainer = $c->container->get_sub_container($subcontainer_name);
+ my @components = $subcontainer->get_service_list;
+ my @result = grep { m{$component} } @components;
- $c->log->warn( Carp::shortmess(qq(Found results for "${component}" 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 $subcontainer->get_component( $result[0], \@args );
+ return map { $subcontainer->get_component( $_, $c, @args ) } @result;
}
}
+ $c->log->warn("Looking for '$component', but nothing was found.");
+
# I would expect to return an empty list here, but that breaks back-compat
}
my $container_class = Class::MOP::load_first_existing_class(@container_classes);
- my $container = $container_class->new( %args,
- name => "$class",
- disable_regex_fallback =>
- $class->config->{disable_component_resolution_regex_fallback},
- );
+ my $container = $container_class->new( %args, name => "$class" );
$class->container($container);
my $config = $container->resolve(service => 'config');
=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 >>.
extends 'Bread::Board::Container';
-has disable_regex_fallback => (
- is => 'ro',
- isa => 'Bool',
- default => 1,
-);
-
has config_local_suffix => (
is => 'ro',
isa => 'Str',
my $self = shift;
return $self->new_sub_container(
- name => 'model',
- disable_regex_fallback => $self->disable_regex_fallback,
+ name => 'model',
);
}
my $self = shift;
return $self->new_sub_container(
- name => 'view',
- disable_regex_fallback => $self->disable_regex_fallback,
+ name => 'view',
);
}
my $self = shift;
return $self->new_sub_container(
- name => 'controller',
- disable_regex_fallback => $self->disable_regex_fallback,
+ name => 'controller',
);
}
extends 'Bread::Board::Container';
-has disable_regex_fallback => (
- is => 'ro',
- isa => 'Bool',
- default => 1,
-);
-
sub get_component {
my ( $self, $name, @args ) = @_;
}
sub get_component_regexp {
- my ( $self, $name, $c, @args ) = @_;
-
- return
- if $self->disable_regex_fallback && !ref $name;
+ my ( $self, $query, $c, @args ) = @_;
- my $query = ref $name ? $name : qr{$name}i;
- my $appname = $self->parent->name;
- $query =~ s/^${appname}:://i;
- $query =~ s/[MVC]|(Model|View|Controller):://i;
+ if (!ref $query) {
+ $c->log->warn("Looking for '$query', but nothing was found.");
+ return;
+ }
my @result = map {
$self->get_component( $_, $c, @args )
} grep { m/$query/ } $self->get_service_list;
- if (!ref $name && $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 $result[0];
- }
-
return @result;
}
# regexp behavior
{
- is_deeply( [ MyApp->comp( qr{Model} ) ], [ 'MyApp::M::Model'], 'regexp ok' );
- is_deeply( [ MyApp->comp('MyApp::V::View$') ], [ 'MyApp::V::View' ], 'Explicit return ok');
- is_deeply( [ MyApp->comp('MyApp::C::Controller$') ], [ 'MyApp::C::Controller' ], 'Explicit return ok');
- is_deeply( [ MyApp->comp('MyApp::M::Model$') ], [ 'MyApp::M::Model' ], 'Explicit return ok');
-
- # a couple other varieties for regexp fallback
- is_deeply( [ MyApp->comp('M::Model') ], [ 'MyApp::M::Model' ], 'Explicit return ok');
+ is_deeply( [ MyApp->comp( qr{Model} ) ], [ 'MyApp::M::Model' ], 'regexp ok' );
{
my $warnings = 0;
no warnings 'redefine';
local *Catalyst::Log::warn = sub { $warnings++ };
- is_deeply( [ MyApp->comp('::M::Model') ], [ 'MyApp::M::Model' ], 'Explicit return ok');
- ok( $warnings, 'regexp fallback warnings' );
-
- $warnings = 0;
- is_deeply( [ MyApp->comp('Mode') ], [ 'MyApp::M::Model' ], 'Explicit return ok');
+ is_deeply( [ MyApp->comp('::M::Model') ], \@complist, 'no reulsts for regexp fallback');
ok( $warnings, 'regexp fallback warnings' );
-
- $warnings = 0;
- is(MyApp->comp('::M::'), 'MyApp::M::Model', 'Regex return ok');
- ok( $warnings, 'regexp fallback for comp() warns' );
}
}
$c->component('M::Model', qw/foo2 bar2/);
is_deeply($args, [qw/foo2 bar2/], 'args passed to ACCEPT_CONTEXT ok');
-
- $c->component('Mode', qw/foo3 bar3/);
- is_deeply($args, [qw/foo3 bar3/], 'args passed to ACCEPT_CONTEXT ok');
}
done_testing;
is($@, '', "Didn't load component twice");
is($appclass->model('TopLevel::Nested')->called,1, 'COMPONENT called once');
-# relying on regex fallback
-ok($appclass->model('TopLevel::Generated'), 'Have generated model');
-is(ref($appclass->model('TopLevel::Generated')), 'FooBarBazQuux',
+ok($appclass->model('TopLevel::GENERATED'), 'Have generated model');
+is(ref($appclass->model('TopLevel::GENERATED')), 'FooBarBazQuux',
'ACCEPT_CONTEXT in generated inner package fired as expected');
$appclass = "InnerComponent";
$warnings = 0;
# object w/ regexp fallback
- is_deeply( [ MyMVCTestApp->model( 'Test' ) ], [ MyMVCTestApp->components->{'MyMVCTestApp::Model::Test::Object'} ], 'Object returned' );
+ is( MyMVCTestApp->model( 'Test' ), undef, 'no regexp fallback' );
ok( $warnings, 'regexp fallback warnings' );
}
- is_deeply( [ MyMVCTestApp->view('MyMVCTestApp::V::View$') ], [ 'MyMVCTestApp::V::View' ], 'Explicit return ok');
- is_deeply( [ MyMVCTestApp->controller('MyMVCTestApp::C::Controller$') ], [ 'MyMVCTestApp::C::Controller' ], 'Explicit return ok');
- is_deeply( [ MyMVCTestApp->model('MyMVCTestApp::M::Model$') ], [ 'MyMVCTestApp::M::Model' ], 'Explicit return ok');
+ is( MyMVCTestApp->view('MyMVCTestApp::V::View$'), undef, 'no regexp fallback');
+
+ is( MyMVCTestApp->controller('MyMVCTestApp::C::Controller$'), undef, 'no regexp fallback');
+
+ is( MyMVCTestApp->model('MyMVCTestApp::M::Model$'), undef, 'no regexp fallback');
}
{
my $x = $c->view('V', qw/foo2 bar2/);
is_deeply($args, [qw/foo2 bar2/], '$c->view args passed to ACCEPT_CONTEXT ok');
- # regexp fallback
- $c->view('::View::V', qw/foo3 bar3/);
- is_deeply($args, [qw/foo3 bar3/], 'args passed to ACCEPT_CONTEXT ok');
-
-
-}
-
-{
- my $warn = '';
- no warnings 'redefine';
- local *Catalyst::Log::warn = sub { $warn .= $_[1] };
-
- is_deeply (MyMVCTestApp->controller('MyMVCTestApp::Controller::C'),
- MyMVCTestApp->components->{'MyMVCTestApp::Controller::C'},
- 'controller by fully qualified name ok');
-
- # You probably meant $c->controller('C') instead of $c->controller({'MyMVCTestApp::Controller::C'})
- my ($suggested_comp_name, $orig_comp_name) = $warn =~ /You probably meant (.*) instead of (.*) /;
- isnt($suggested_comp_name, $orig_comp_name, 'suggested fix in warning for fully qualified component names makes sense' );
}
{
# try to get nonexisting object w/o regexp fallback
is( MyApp::WithoutRegexFallback->controller('Foo'), undef, 'no controller Foo found');
- ok( !$warnings, 'no regexp fallback warnings' );
}
-done_testing();
+done_testing;