develooper Front page | perl.perl5.porters | Postings from August 2009

[perl #68654] next::method doesn't see UNIVERSAL superclasses

From:
Zefram
Date:
August 19, 2009 02:59
Subject:
[perl #68654] next::method doesn't see UNIVERSAL superclasses
Message ID:
rt-3.6.HEAD-2466-1250628440-1755.68654-75-0@perl.org
# New Ticket Created by  Zefram 
# Please include the string:  [perl #68654]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=68654 >



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


-----------------------------------------------------------------
[Please enter your report here]

Here's a simple use of next::method:

$ perl -Mmro -lwe '{ package U; sub foo { print "foo" } } { package M; @ISA = qw(U); sub foo { $_[0]->next::method } } M->foo' 
foo

Here's something that should behave equivalently but doesn't:

$ perl -Mmro -lwe '{ package UNIVERSAL; sub foo { print "foo" } } { package M; sub foo { $_[0]->next::method } } M->foo'
No next::method 'foo' found for M at /usr/share/perl/5.10/mro.pm line 26.

The inheritance pattern is the same here; the differences are that
class U has been replaced by UNIVERSAL, and M being a subclass of it is
now implicit.  It can be made to work again by making M's inheritance
explicit:

$ perl -Mmro -lwe '{ package UNIVERSAL; sub foo { print "foo" } } { package M; @ISA = qw(UNIVERSAL); sub foo { $_[0]->next::method } } M->foo'
foo

In the work where I ran into this, I'm not actually working with UNIVERSAL
directly, but attempting to combine methods in superclasses of UNIVERSAL.
The same problem occurs whenever the next method is located in UNIVERSAL
or any of its superclasses, even if the method invoking next::method is
itself in such a universal class.  But it does work if the invocant is
"UNIVERSAL" itself, or if the inheritance is made explicit.  Apparently
next::method doesn't consider any implicit superclass relationships when
deciding on the list of classes to look for methods in.

In my situation, where the code that calls next::method is in a universal
superclass, I can work around the problem by doing UNIVERSAL->next::can
and then using the returned code ref as a method on the original invocant.
Code that runs in a non-universal class would have more difficulty:
it would have to try next::can on the original invocant, and then if
that returns undef move on to UNIVERSAL->next::can.

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

Configured by Debian Project at Thu Jan  1 12:43:38 UTC 2009.

Summary of my perl5 (revision 5 version 10 subversion 0) configuration:
  Platform:
    osname=linux, osvers=2.6.26-1-686, archname=i486-linux-gnu-thread-multi
    uname='linux rebekka 2.6.26-1-686 #1 smp mon dec 15 18:15:07 utc 2008 i686 gnulinux '
    config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i486-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.10 -Darchlib=/usr/lib/perl/5.10 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.10.0 -Dsitearch=/usr/local/lib/perl/5.10.0 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib -Dlibperl=libperl.so.5.10.0 -Dd_dosuid -des'
    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 -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2 -g',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -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 =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib /usr/lib64
    libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
    perllibs=-ldl -lm -lpthread -lc -lcrypt
    libc=/lib/libc-2.7.so, so=so, useshrplib=true, libperl=libperl.so.5.10.0
    gnulibc_version='2.7'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -g -L/usr/local/lib'

Locally applied patches:
    

---
@INC for perl 5.10.0:
    /etc/perl
    /usr/local/lib/perl/5.10.0
    /usr/local/share/perl/5.10.0
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.10
    /usr/share/perl/5.10
    /usr/local/lib/site_perl
    .

---
Environment for perl 5.10.0:
    HOME=/home/zefram
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/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