Fix the super recursion bug perigrin found
Dave Rolsky [Mon, 12 Jan 2009 00:52:42 +0000 (00:52 +0000)]
Changes
lib/Moose.pm
lib/Moose/Meta/Method/Overriden.pm

diff --git a/Changes b/Changes
index 51b56c0..51cf345 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,6 +1,11 @@
 Revision history for Perl extension Moose
 
-Pending
+0.65
+    * Moose and Moose::Meta::Method::Overridden
+      - If an overridden method called super(), and then the
+        superclass's method (not overridden) _also_ called super(),
+        Moose went into an endless recursion loop. Test provided by
+        Chris Prather. (Dave Rolsky)
     * Moose::Meta::TypeConstraint
       - Add some explanation for a few explanationless methods (gphat)
 
index 45ac965..504096a 100644 (file)
@@ -94,8 +94,15 @@ sub around {
     Moose::Util::add_method_modifier($class, 'around', \@_);
 }
 
+our $SUPER_PACKAGE;
+our $SUPER_BODY;
+our @SUPER_ARGS;
+
 sub super {
-    return unless our $SUPER_BODY; $SUPER_BODY->(our @SUPER_ARGS);
+    # This check avoids a recursion loop - see
+    # t/100_bugs/020_super_recursion.t
+    return if defined $SUPER_PACKAGE && $SUPER_PACKAGE ne caller();
+    return unless $SUPER_BODY; $SUPER_BODY->(@SUPER_ARGS);
 }
 
 sub override {
index 589dcad..a3bd26a 100644 (file)
@@ -16,7 +16,7 @@ sub new {
     # it is really more like body's compilation stash
     # this is where we need to override the definition of super() so that the
     # body of the code can call the right overridden version
-    my $_super_package = $args{package} || $args{class}->name;
+    my $super_package = $args{package} || $args{class}->name;
 
     my $name = $args{name};
 
@@ -30,13 +30,14 @@ sub new {
     my $method = $args{method};
 
     my $body = sub {
+        local $Moose::SUPER_PACKAGE = $super_package;
         local @Moose::SUPER_ARGS = @_;
         local $Moose::SUPER_BODY = $super_body;
         return $method->(@_);
     };
 
     # FIXME do we need this make sure this works for next::method?
-    # subname "${_super_package}::${name}", $method;
+    # subname "${super_package}::${name}", $method;
 
     # FIXME store additional attrs
     $class->wrap(