X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst.pm;h=fd57ca6d4742065d25a806567b2f3baee108b62f;hb=9d286ef65c75378a7dc46a6ddbe1c7fe445890db;hp=d5f5ec8fea59acc38f334d85f40478fd01d3b3bd;hpb=f723794a21b143f495fc00a4584efcfee4c14fa7;p=catagits%2FCatalyst-Runtime.git diff --git a/lib/Catalyst.pm b/lib/Catalyst.pm index d5f5ec8..fd57ca6 100644 --- a/lib/Catalyst.pm +++ b/lib/Catalyst.pm @@ -79,7 +79,7 @@ __PACKAGE__->stats_class('Catalyst::Stats'); # Remember to update this in Catalyst::Runtime as well! -our $VERSION = '5.80032'; +our $VERSION = '5.80033'; sub import { my ( $class, @arguments ) = @_; @@ -560,9 +560,48 @@ sub _comp_names_search_prefixes { return @result if @result; - $c->log->warn("Looking for '$name', but nothing was found."); + # if we were given a regexp to search against, we're done. + return if ref $name; + + # 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; + return @result; } # Find possible names for a prefix @@ -793,6 +832,12 @@ should be used instead. 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 { @@ -815,9 +860,21 @@ sub component { my( $comp ) = $c->_comp_search_prefixes( $name, qw/Model M Controller C View V/ ); return $c->_filter_component( $comp, @args ) if $comp; } - else { - my @result = grep { m{$name} } keys %{ $c->components }; - return map { $c->_filter_component( $_, @args ) } @result; + + return + if $c->config->{disable_component_resolution_regex_fallback}; + + # This is here so $c->comp( '::M::' ) works + my $query = ref $name ? $name : qr{$name}i; + + my @result = grep { m{$query} } keys %{ $c->components }; + return map { $c->_filter_component( $_, @args ) } @result if ref $name; + + 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 ); } # I would expect to return an empty list here, but that breaks back-compat @@ -2869,6 +2926,14 @@ C - The default view to be rendered or returned when C<< $c->view =item * +C - 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 will be returned. + +=item * + C - 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 >>.