The following is a debug session on Perl 5.12. Does this make any sense? Does UNIVERSAL
cache a version of the @ISA
variable, which if forever uses thereafer. Back before Class::ISA
was deprecated, I used to call Class::ISA::self_and_super_path
to get the internals to relook at the @ISA
array. Since it is now considered unnecessary, how do you get perl to audit its internal records?
DB<34> p $papa
Papushka=HASH(0x16bc0300)
DB<35> p $papa->isa('Nanushka')
DB<36> p $papa->isa('Babushka')
1
DB<37> x @Papushka::ISA
0 'Nanushka'
1 'Babushka'
This is test code (obviously). It's getting the same results, run flat, run as a test, or run in debug. I should tell you that prior to this @ISA = qw<Babushka>
and I performed
splice( @ISA, 0, 0, 'Nanushka' );
Is that the problem? Should you only ever push
onto @ISA
?
Yes, there is a cache. But if you can modify
@ISA
without invalidating that cache, I would consider it a bug in perl.Does your problem disappear if you add the line
@ISA = @ISA;
after yoursplice
line?The replacement for
Class::ISA::self_and_super_path
ismro::get_linear_isa
. That's available either frommro
itself, or, if you want to support old perls, viaMRO::Compat
.Also,
@ISA
is a magic variable.Note the
PERL_MAGIC_isa
. That's what drives this particular mechanism.Whenever it is changed, the contents of any caches that rely on its value are supposed to be updated.
Apparently you've found a case where the cache invalidation doesn't happen. I consider this a bug. Chances are
splice
, for some reason, doesn't invoke theisa
magic appropriately. You could try to modify@ISA
in an alternative way, for example usingunshift
or an assignment, or possibly trymro::method_changed_in
, which would invalidate the method resolution caches, which are bound to the various@ISA
s.If you could reduce this bug to a minimal testcase, that'd be hugely helpful in getting this bug fixed.
Update:
A minimal testcase turned out to be easy:
This is caused by
pp_splice
not doing something likemg_set((SV *)ary)
.push
,unshift
, and regular assignments do that correctly, so using one of these should fix your issue.Another Update:
This change, which I just committed to perl, fixes the issue. However, as the odd behaviour of
splice
not invoking magic is already present in 5.8 and 5.10, it's not a regression and therefore not going to be part of 5.12.3 in a few months. 5.13.6, which will be released next week, and 5.14.0, next northern spring, will probably have it.