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
-
[perl #68654] next::method doesn't see UNIVERSAL superclasses
by Zefram