Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

next::method loops on UNIVERSAL superclasses #10915

Closed
p5pRT opened this issue Dec 21, 2010 · 6 comments
Closed

next::method loops on UNIVERSAL superclasses #10915

p5pRT opened this issue Dec 21, 2010 · 6 comments

Comments

@p5pRT
Copy link

p5pRT commented Dec 21, 2010

Migrated from rt.perl.org#81098 (status was 'resolved')

Searchable as RT81098$

@p5pRT
Copy link
Author

p5pRT commented Dec 21, 2010

From zefram@fysh.org

Created by zefram@fysh.org

a5cd004 and 1726bc1 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 a5cd004, but didn't chase it down at the time. 1726bc1 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
a5cd004 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.

Perl Info

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

@p5pRT
Copy link
Author

p5pRT commented Dec 26, 2010

From @cpansprout

On Tue Dec 21 12​:23​:19 2010, zefram@​fysh.org wrote​:

a5cd004 and 1726bc1 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 a5cd004, but didn't chase it down at the time. 1726bc1 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
a5cd004 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.)

@p5pRT
Copy link
Author

p5pRT commented Dec 26, 2010

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jan 3, 2011

From @obra

On Sun 26.Dec'10 at 13​:31​:36 -0800, Father Chrysostomos via RT wrote​:

On Tue Dec 21 12​:23​:19 2010, zefram@​fysh.org wrote​:

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.)

That seems reasonable, yes. :/ Thanks for paying attention to this.

-j

@p5pRT
Copy link
Author

p5pRT commented Jan 3, 2011

From @cpansprout

On Sun Jan 02 21​:09​:45 2011, jesse wrote​:

On Sun 26.Dec'10 at 13​:31​:36 -0800, Father Chrysostomos via RT wrote​:

On Tue Dec 21 12​:23​:19 2010, zefram@​fysh.org wrote​:

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.)

That seems reasonable, yes. :/ Thanks for paying attention to this.

-j

I have just reverted them with 884491d and 7f7845e.

@p5pRT
Copy link
Author

p5pRT commented Jan 3, 2011

@cpansprout - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant