Fix model/view/controller methods to handle stringifiable objects
Matt S Trout [Tue, 14 Aug 2012 17:48:43 +0000 (17:48 +0000)]
Previously, uri_for would test to see if its first argument was isa
Catalyst::Controller but then assume any other object was a Catalyst::Action;
this change uses Safe::Isa to check the class in both cases, which is useful
both for string overloading packages such as i18n.pm and HTML::String but also
when a Path::Class::File object is passed during static URI generation.

Changes
lib/Catalyst.pm
t/aggregate/unit_core_uri_for.t

diff --git a/Changes b/Changes
index 06eadd6..a9ef82d 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,6 @@
 # This file documents the revision history for Perl extension Catalyst.
 
+  - Fix uri_for to handle a stringifiable object
   - Fix model/view/controller methods to handle stringifiable objects
   - Fix RT#78377 - IIS7 ignores response body for 3xx requests, which
     causes (a different) response to be broken when using keepalive.
index 2f9225f..559f76b 100644 (file)
@@ -1270,7 +1270,7 @@ path, use C<< $c->uri_for_action >> instead.
 sub uri_for {
     my ( $c, $path, @args ) = @_;
 
-    if (blessed($path) && $path->isa('Catalyst::Controller')) {
+    if ( $path->$_isa('Catalyst::Controller') ) {
         $path = $path->path_prefix;
         $path =~ s{/+\z}{};
         $path .= '/';
@@ -1287,7 +1287,7 @@ sub uri_for {
         $arg =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go;
     }
 
-    if ( blessed($path) ) { # action object
+    if ( $path->$_isa('Catalyst::Action') ) { # action object
         s|/|%2F|g for @args;
         my $captures = [ map { s|/|%2F|g; $_; }
                         ( scalar @args && ref $args[0] eq 'ARRAY'
index 6732024..3318192 100644 (file)
@@ -181,5 +181,16 @@ TODO: {
     );
 }
 
-done_testing;
+{
+    package MyStringThing;
+
+    use overload '""' => sub { $_[0]->{string} }, fallback => 1;
+}
 
+is(
+    Catalyst::uri_for( $context, bless( { string => 'test' }, 'MyStringThing' ) ),
+    'http://127.0.0.1/test',
+    'overloaded object handled correctly'
+);
+
+done_testing;