const char *hvname;
I32 entries;
struct mro_meta* selfmeta;
+ bool seen_univ = FALSE;
HV* nmcache;
I32 i;
PPCODE:
/* Now search the remainder of the MRO for the
same method name as the contextually enclosing
method */
+ retry:
if(entries > 0) {
while (entries--) {
SV * const linear_sv = *linear_svp++;
assert(curstash);
+ if (!seen_univ && SvCUR(linear_sv) == 9
+ && strnEQ(SvPV_nolen_const(linear_sv), "UNIVERSAL", 9))
+ seen_univ = TRUE;
+
gvp = (GV**)hv_fetch(curstash, subname, subname_len, 0);
if (!gvp) continue;
}
}
+ if (!seen_univ && (selfstash = gv_stashpvn("UNIVERSAL", 9, 0))) {
+ linear_av = S_mro_get_linear_isa_c3(aTHX_ selfstash, 0);
+ linear_svp = AvARRAY(linear_av);
+ entries = AvFILLp(linear_av) + 1;
+ seen_univ = TRUE;
+ goto retry;
+ }
+
(void)hv_store_ent(nmcache, sv, &PL_sv_undef, 0);
if(throw_nomethod)
Perl_croak(aTHX_ "No next::method '%s' found for %s", subname, hvname);
BEGIN { chdir 't'; require q(./test.pl); @INC = qw "../lib lib" }
-plan(tests => 12);
+plan(tests => 14);
{
is($@, '', "->next::can on non-existing package name");
}
+
+# Test next::method with UNIVERSAL methods
+{
+ package UNIVERSAL;
+ sub foo { "foo" }
+ our @ISA = "a";
+ package a;
+ sub bar { "bar" }
+ package M;
+ sub foo { shift->next::method }
+ sub bar { shift->next::method }
+ package main;
+
+ is eval { M->foo }, "foo", 'next::method with implicit UNIVERSAL';
+ is eval { M->bar }, "bar", 'n::m w/superclass of implicit UNIVERSAL';
+}