diff options
author | Father Chrysostomos <sprout@cpan.org> | 2010-11-12 16:34:02 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2010-11-12 16:34:28 -0800 |
commit | 90ba1f34dee5c0381e098e7c0435f354e2e70cf8 (patch) | |
tree | 327d515f3969b762a7014a86fcb9dfff67a4cf97 /t/mro | |
parent | fd0eba1997caf19767d67b8336533666df3fea90 (diff) | |
download | perl-90ba1f34dee5c0381e098e7c0435f354e2e70cf8.tar.gz |
Update isarev when clobbered class has subsubclasses
This fixes a case that mro_package_moved did not take into account:
If a class with multiple levels of subclasses was assigned over, then,
depending on the order in which the subclasses were processed in the
second loop in mro_package_moved, the subclasses might not be removed
from the isarev hashes of superclasses of the clobbered class.
This was because a call to mro_isa_changed_in on one class could call
mro_get_linear_isa on another class in the list, overwriting its
meta->isa hash, which is used to determine what to delete from
PL_isarev.
E.g., if D isa C isa B isa A, this assignment:
*B:: = *something::;
would cause B, C and D to be iterated over, but not in any particular
order. The order could be D, C, B, in which case mro_isa_changed_in(D)
would overwrite the meta->isa hash in C with one that did not list A.
So mro_isa_changed_in(C) would not see A in meta->isa and would not
delete PL_isarev->{A}{C}.
This commit stores the meta->isa hash as the value in the ‘big list’,
instead of the stash. The stash itself can be retrieved from the key,
since it is already a memory address (a pointer cast to a char array).
The recorded isa hash in inserted into each stash before the call to
mro_isa_changed_in.
Diffstat (limited to 't/mro')
-rw-r--r-- | t/mro/isarev.t | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/t/mro/isarev.t b/t/mro/isarev.t index 05312cc78e..3c3692e5ad 100644 --- a/t/mro/isarev.t +++ b/t/mro/isarev.t @@ -10,7 +10,7 @@ BEGIN { use strict; use warnings; -plan(tests => 22); +plan(tests => 23); use mro; @@ -132,3 +132,12 @@ i beta => qw [], "undeffing an ISA glob deletes isarev entries"; $_ = \*az::ISA; undef *az::; i buki => qw [], "undeffing a package glob deletes isarev entries"; + +# Package aliasing/clobbering when the clobbered package has grandchildren +# by inheritance. +@bar::ISA = 'phoo'; +@subclassA::ISA = "subclassB"; +@subclassB::ISA = "bar"; +*bar:: = *baz::; +i phoo => qw [], + 'clobbering a class w/multiple layers of subclasses updates its parent'; |