summaryrefslogtreecommitdiff
path: root/t/mro
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2010-11-12 16:34:02 -0800
committerFather Chrysostomos <sprout@cpan.org>2010-11-12 16:34:28 -0800
commit90ba1f34dee5c0381e098e7c0435f354e2e70cf8 (patch)
tree327d515f3969b762a7014a86fcb9dfff67a4cf97 /t/mro
parentfd0eba1997caf19767d67b8336533666df3fea90 (diff)
downloadperl-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.t11
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';