Detect redispatch exceptions by a class check, not by checking the exception message.
[catagits/Catalyst-Runtime.git] / lib / Catalyst.pm
index 62fc85b..a751984 100644 (file)
@@ -1,11 +1,14 @@
 package Catalyst;
 
 use Moose;
+use Moose::Meta::Class ();
 extends 'Catalyst::Component';
 use Moose::Util qw/find_meta/;
 use bytes;
 use B::Hooks::EndOfScope ();
 use Catalyst::Exception;
+use Catalyst::Exception::Detach;
+use Catalyst::Exception::Go;
 use Catalyst::Log;
 use Catalyst::Request;
 use Catalyst::Request::Upload;
@@ -57,8 +60,8 @@ sub finalize_output { shift->finalize_body(@_) };
 our $COUNT     = 1;
 our $START     = time;
 our $RECURSION = 1000;
-our $DETACH    = "catalyst_detach\n";
-our $GO        = "catalyst_go\n";
+our $DETACH    = Catalyst::Exception::Detach->new;
+our $GO        = Catalyst::Exception::Go->new;
 
 #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?
@@ -75,7 +78,7 @@ __PACKAGE__->stats_class('Catalyst::Stats');
 
 # Remember to update this in Catalyst::Runtime as well!
 
-our $VERSION = '5.80003';
+our $VERSION = '5.80005';
 
 {
     my $dev_version = $VERSION =~ /_\d{2}$/;
@@ -492,8 +495,13 @@ sub clear_errors {
     $c->error(0);
 }
 
-# search components given a name and some prefixes
 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 ) . ')::';
@@ -509,18 +517,18 @@ sub _comp_search_prefixes {
     my $query  = ref $name ? $name : qr/^$name$/i;
     my @result = grep { $eligible{$_} =~ m{$query} } keys %eligible;
 
-    return map { $c->components->{ $_ } } @result if @result;
+    return @result if @result;
 
     # if we were given a regexp to search against, we're done.
     return if ref $name;
 
     # regexp fallback
     $query  = qr/$name/i;
-    @result = map { $c->components->{ $_ } } grep { $eligible{ $_ } =~ m{$query} } keys %eligible;
+    @result = grep { $eligible{ $_ } =~ m{$query} } keys %eligible;
 
     # no results? try against full names
     if( !@result ) {
-        @result = map { $c->components->{ $_ } } grep { m{$query} } keys %eligible;
+        @result = grep { m{$query} } keys %eligible;
     }
 
     # don't warn if we didn't find any results, it just might not exist
@@ -557,7 +565,9 @@ sub _comp_names {
 
     my $filter = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
 
-    my @names = map { s{$filter}{}; $_; } $c->_comp_search_prefixes( undef, @prefixes );
+    my @names = map { s{$filter}{}; $_; }
+        $c->_comp_names_search_prefixes( undef, @prefixes );
+
     return @names;
 }
 
@@ -903,7 +913,9 @@ Returns the engine instance. See L<Catalyst::Engine>.
 =head2 $c->path_to(@path)
 
 Merges C<@path> with C<< $c->config->{home} >> and returns a
-L<Path::Class::Dir> object.
+L<Path::Class::Dir> object. Note you can usually use this object as
+a filename, but sometimes you will have to explicitly stringify it
+yourself by calling the C<<->stringify>> method.
 
 For example:
 
@@ -1100,9 +1112,10 @@ EOF
     # modifiers work correctly in MyApp (as you have to call setup _before_
     # applying modifiers).
     B::Hooks::EndOfScope::on_scope_end {
+        return if $@;
         my $meta = Class::MOP::get_metaclass_by_name($class);
         if ( $meta->is_immutable && ! { $meta->immutable_options }->{inline_constructor} ) {
-            die "You made your application class ($class) immutable, "
+            warn "You made your application class ($class) immutable, "
                 . "but did not inline the constructor.\n"
                 . "This will break catalyst, please pass "
                 . "(replace_constructor => 1) when making your class immutable.\n";
@@ -1159,7 +1172,7 @@ using C<< $c->req->captures >>.
   $c->uri_for($c->action, $c->req->captures);
 
   # For the Foo action in the Bar controller
-  $c->uri_for($c->controller->('Bar')->action_for('Foo'), $c->req->captures);
+  $c->uri_for($c->controller('Bar')->action_for('Foo'), $c->req->captures);
 
 =back
 
@@ -1188,7 +1201,7 @@ sub uri_for {
       ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} );
 
     carp "uri_for called with undef argument" if grep { ! defined $_ } @args;
-    s/([^A-Za-z0-9\-_.!~*'()])/$URI::Escape::escapes{$1}/go for @args;
+    s/([^$URI::uric])/$URI::Escape::escapes{$1}/go for @args;
 
     unshift(@args, $path);
 
@@ -1222,7 +1235,7 @@ sub uri_for {
               $_ = "$_";
               utf8::encode( $_ ) if utf8::is_utf8($_);
               # using the URI::Escape pattern here so utf8 chars survive
-              s/([^A-Za-z0-9\-_.!~*'()])/$URI::Escape::escapes{$1}/go;
+              s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go;
               s/ /+/g;
               "${key}=$_"; } ( ref $val eq 'ARRAY' ? @$val : $val ));
       } @keys);
@@ -1498,10 +1511,10 @@ sub execute {
     my $last = pop( @{ $c->stack } );
 
     if ( my $error = $@ ) {
-        if ( !ref($error) and $error eq $DETACH ) {
+        if ( blessed($error) and $error->isa('Catalyst::Exception::Detach') ) {
             die $DETACH if($c->depth > 1);
         }
-        elsif ( !ref($error) and $error eq $GO ) {
+        elsif ( blessed($error) and $error->isa('Catalyst::Exception::Go') ) {
             die $GO if($c->depth > 0);
         }
         else {
@@ -2174,7 +2187,7 @@ sub setup_components {
 sub _controller_init_base_classes {
     my ($app_class, $component) = @_;
     foreach my $class ( reverse @{ mro::get_linear_isa($component) } ) {
-        Moose->init_meta( for_class => $class )
+        Moose::Meta::Class->initialize( $class )
             unless find_meta($class);
     }
 }
@@ -2478,9 +2491,6 @@ the plugin name does not begin with C<Catalyst::Plugin::>.
         my ( $proto, $plugin, $instant ) = @_;
         my $class = ref $proto || $proto;
 
-        # no ignore_loaded here, the plugin may already have been
-        # defined in memory and we don't want to error on "no file" if so
-
         Class::MOP::load_class( $plugin );
 
         $proto->_plugins->{$plugin} = 1;
@@ -2501,14 +2511,26 @@ the plugin name does not begin with C<Catalyst::Plugin::>.
 
         $class->_plugins( {} ) unless $class->_plugins;
         $plugins ||= [];
-        for my $plugin ( reverse @$plugins ) {
+                
+        my @plugins = Catalyst::Utils::resolve_namespace($class . '::Plugin', 'Catalyst::Plugin', @$plugins);
 
-            unless ( $plugin =~ s/\A\+// ) {
-                $plugin = "Catalyst::Plugin::$plugin";
-            }
+        for my $plugin ( reverse @plugins ) {
+            Class::MOP::load_class($plugin);
+            my $meta = find_meta($plugin);
+            next if $meta && $meta->isa('Moose::Meta::Role');
 
             $class->_register_plugin($plugin);
         }
+
+        my @roles =
+            map { $_->name }
+            grep { $_ && blessed($_) && $_->isa('Moose::Meta::Role') }
+            map { find_meta($_) }
+            @plugins;
+
+        Moose::Util::apply_all_roles(
+            $class => @roles
+        ) if @roles;
     }
 }
 
@@ -2700,6 +2722,8 @@ dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
 
 Drew Taylor
 
+dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
+
 esskar: Sascha Kiefer
 
 fireartist: Carl Franks <cfranks@cpan.org>
@@ -2748,6 +2772,8 @@ phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
 
 rafl: Florian Ragwitz <rafl@debian.org>
 
+random: Roland Lammel <lammel@cpan.org>
+
 sky: Arthur Bergman
 
 the_jester: Jesse Sheidlower
@@ -2760,7 +2786,7 @@ willert: Sebastian Willert <willert@cpan.org>
 
 =head1 LICENSE
 
-This library is free software, you can redistribute it and/or modify it under
+This library is free software. You can redistribute it and/or modify it under
 the same terms as Perl itself.
 
 =cut