替代品为Class::ISA::self_and_super_path
is mro::get_linear_isa
。这可以从mro
本身,或者,如果你想支持旧的 perls,通过MRO::Compat
.
Also, @ISA
是一个神奇的变量。
$ perl -MDevel::Peek -e'Dump \@ISA'
SV = IV(0x1b92e20) at 0x1b92e28
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x1bbcd58
SV = PVAV(0x1b93cf8) at 0x1bbcd58
REFCNT = 2
FLAGS = (SMG,RMG)
MAGIC = 0x1bc0f68
MG_VIRTUAL = &PL_vtbl_isa
MG_TYPE = PERL_MAGIC_isa(I)
MG_OBJ = 0x1bbcd40
ARRAY = 0x0
FILL = -1
MAX = -1
ARYLEN = 0x0
FLAGS = (REAL)
请注意PERL_MAGIC_isa
。这就是驱动这个特殊机制的原因。
每当它发生更改时,依赖于其值的任何缓存的内容都应该被更新。
$ perl -E'say Foo->isa(q[Bar]) || 0; @Foo::ISA = qw(Bar Baz); say Foo->isa(q[Bar]) || 0'
0
1
显然您已经发现了缓存失效不会发生的情况。我认为这是一个错误。机会是splice
出于某种原因,不会调用isa
适当地施魔法。你可以尝试修改@ISA
以另一种方式,例如使用unshift
或作业,或者可能尝试mro::method_changed_in
,这将使方法解析缓存无效,这些缓存绑定到各种@ISA
s.
如果您可以将此错误减少到最小的测试用例,那么这对于修复此错误将非常有帮助。
Update:
事实证明,一个最小的测试用例很简单:
$ perl -E'say Foo->isa(q[Bar]) || 0; splice @Foo::ISA, 0, 0, q[Bar]; say Foo->isa(q[Bar]) || 0'
0
0
这是由于pp_splice
不做类似的事情mg_set((SV *)ary)
. push
, unshift
,并且常规作业可以正确执行此操作,因此使用其中之一应该可以解决您的问题。
另一个更新:
这个改变 http://perl5.git.perl.org/perl.git/commitdiff/474af99058f4c0fc3b80d73763da5b29c1ff8c66,我刚刚提交给 perl,解决了这个问题。然而,由于splice
不调用魔法已经存在于 5.8 和 5.10 中,这不是回归,因此几个月后不会成为 5.12.3 的一部分。下周发布的 5.13.6 和明年北方春天的 5.14.0 可能会有它。