develooper Front page | perl.perl5.porters | Postings from December 2010

[perl #81098] next::method loops on UNIVERSAL superclasses

Thread Next
Father Chrysostomos via RT
December 26, 2010 13:31
[perl #81098] next::method loops on UNIVERSAL superclasses
Message ID:
On Tue Dec 21 12:23:19 2010, wrote:
> a5cd004d and 1726bc11 supposedly fixed [perl #68654] "next::method
> doesn't see UNIVERSAL", but actually they have just turned the bug
>    into
> something similar and just as bad.  Now, if next::method et al are
>    called
> from within a method on a universal superclass, they pick up the first
> version of the method that is provided by any universal superclass,
> even though that is the currently executing method or even earlier in
> the chain.  Minimal test:
> $ perl5.13.7 -Mmro -lwe '{ package UNIVERSAL; sub foo { print "foo";
>    $_[0]->next::method; } } M->foo'
> foo
> No next::method 'foo' found for M at
>    /home/zefram/usr/perl/perl_install/perl-5.13.7-i32-
>    f52/lib/5.13.7/i386-linux-thread-multi/ line 27.
> $ perl5.13.8 -Mmro -lwe '{ package UNIVERSAL; sub foo { print "foo";
>    $_[0]->next::method; } } M->foo'
> foo
> foo
> foo
> foo
> foo
> ^C
> More extensive demonstration:
> $ perl5.13.8 -Mmro -lwe '{ package A; sub foo { print "A foo, next is
>    ", $_[0]->next::can; } } { package B; sub foo { print "B foo, next
>    is ", $_[0]->next::can; } } @UNIVERSAL::ISA=qw(A B); { package M;
>    sub foo { $_[0]->next::method } } print "A::foo is ", \&A::foo;
>    print "B::foo is ", \&B::foo; print "M foo is ", \&M::foo; M->foo;
>    M->A::foo; M->B::foo'
> A::foo is CODE(0x9b62f80)
> B::foo is CODE(0x9b63090)
> M foo is CODE(0x9b729b0)
> A foo, next is CODE(0x9b62f80)
> A foo, next is CODE(0x9b62f80)
> B foo, next is CODE(0x9b62f80)
> I must confess, I was worried by the "retry with UNIVERSAL"
>    description
> of a5cd004d, but didn't chase it down at the time.  1726bc11 made
> me less worried.  Now that 5.13.8 is out with this change, I've
> revisited Attribute::Lexical to try removing the workaround for
> [perl #68654].  It turns out that removing the workaround (by changing
> _KLUDGE_UNIVERSAL_INVOCANT to be false on 5.13.8) makes A:L
>    immediately
> run into an infinite recursion.  ([ #63531] indicates that
> a5cd004d alone makes A:L run into an infinite loop *with* the
>    workaround.)
> It seems to me that next::can is too late a stage for the special-
>    casing
> of UNIVERSAL.  The whole concept of handling it there supposes that
> inheritance through UNIVERSAL is separate from non-universal
>    inheritance.
> In reality it's not; the only difference is that the UNIVERSAL
>    superclass
> is implicit.  UNIVERSAL and its superclasses ought to be integrated
> into the linear ISA (the class precedence list) at an earlier stage,
> and the whole linear ISA should be treated consistently.

That sounds like a good idea. I am not comfortable with such a change
this close to 5.14. (I need to think about the implications on the MRO
API, if any.)

So perhaps I should just revert those two fixes for now. (After all, an
old bug is better than a new one.)

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About