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

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

From:
Zefram
Date:
December 21, 2010 13:34
Subject:
[perl #81098] next::method loops on UNIVERSAL superclasses
Message ID:
rt-3.6.HEAD-5425-1292962999-157.81098-75-0@perl.org
# New Ticket Created by  Zefram 
# Please include the string:  [perl #81098]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=81098 >



This is a bug report for perl from zefram@fysh.org,
generated with the help of perlbug 1.39 running under perl 5.13.8.


-----------------------------------------------------------------
[Please describe your issue here]

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/mro.pm 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.  ([rt.cpan.org #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.

[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
    category=core
    severity=medium
---
Site configuration information for perl 5.13.8:

Configured by zefram at Sun Dec 19 21:41:29 GMT 2010.

Summary of my perl5 (revision 5 version 13 subversion 8) configuration:
   
  Platform:
    osname=linux, osvers=2.6.26-2-686, archname=i386-linux-thread-multi
    uname='linux vigo.rous.org 2.6.26-2-686 #1 smp thu nov 25 01:53:57 utc 2010 i686 gnulinux '
    config_args='-des -Darchname=i386-linux -Dcccdlflags=-fPIC -Dccdlflags=-rdynamic -Dprefix=/home/zefram/usr/perl/perl_install/perl-5.13.8-i32-f52 -Dman1ext=1 -Dman3ext=3perl -Duselargefiles -Dusethreads -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dusedevel -Uversiononly -Ui_db'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.3.2', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lnsl -lgdbm -ldl -lm -lcrypt -lutil -lpthread -lc -lgdbm_compat
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=/lib/libc-2.7.so, so=so, useshrplib=true, libperl=libperl.so
    gnulibc_version='2.7'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic -Wl,-rpath,/home/zefram/usr/perl/perl_install/perl-5.13.8-i32-f52/lib/5.13.8/i386-linux-thread-multi/CORE'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector'

Locally applied patches:
    

---
@INC for perl 5.13.8:
    /home/zefram/usr/perl/perl_install/perl-5.13.8-i32-f52/lib/site_perl/5.13.8/i386-linux-thread-multi
    /home/zefram/usr/perl/perl_install/perl-5.13.8-i32-f52/lib/site_perl/5.13.8
    /home/zefram/usr/perl/perl_install/perl-5.13.8-i32-f52/lib/5.13.8/i386-linux-thread-multi
    /home/zefram/usr/perl/perl_install/perl-5.13.8-i32-f52/lib/5.13.8
    .

---
Environment for perl 5.13.8:
    HOME=/home/zefram
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/zefram/usr/perl/perl_install/perl-5.13.8-i32-f52/bin:/home/zefram/usr/perl/util:/home/zefram/pub/i686-pc-linux-gnu/bin:/home/zefram/pub/common/bin:/usr/bin:/usr/X11R6/bin:/bin:/usr/local/bin:/usr/games
    PERL_BADLANG (unset)
    SHELL=/usr/bin/zsh




nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About