summaryrefslogtreecommitdiff
path: root/t/mro
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2010-11-11 20:29:31 -0800
committerFather Chrysostomos <sprout@cpan.org>2010-11-11 20:32:28 -0800
commitb89cdb229b520dceadf180df9462c8a0a1edf975 (patch)
tree8a0be1856770d067e6569f7247f2c484bbec70a0 /t/mro
parenteda19b455e8d9bb196ce7fa823d633ff077b2390 (diff)
downloadperl-b89cdb229b520dceadf180df9462c8a0a1edf975.tar.gz
Fix package assignment with nested aliased packages
This commit fixes package assignments like *foo:: = *bar:: when both foo and bar contain nested stashes that are aliases of each other. mro_package_moved (actually, its auxiliary routine) need to keep a list of stashes that have been seen as a separate list from those that are going to have mro_isa_changed_in called on them. Otherwise, some stashes will simply not be iterated through. See the test that this adds and its comments. @ISA = @ISA should never have any effect visible to Perl (with a capital), but it does in that test case, prior to this commit. This also fixes another bug that the test case triggered: riter was not being reset before the second iteration in mro_gather_and_rename. Also, the stashes HV (aka the ‘big list’) now holds refcounts on its elements, as that makes the code simpler as a result of the changes.
Diffstat (limited to 't/mro')
-rw-r--r--t/mro/package_aliases.t30
1 files changed, 29 insertions, 1 deletions
diff --git a/t/mro/package_aliases.t b/t/mro/package_aliases.t
index b4ef2027fe..f2c5c3944f 100644
--- a/t/mro/package_aliases.t
+++ b/t/mro/package_aliases.t
@@ -10,7 +10,7 @@ BEGIN {
use strict;
use warnings;
-plan(tests => 19);
+plan(tests => 20);
{
package New;
@@ -236,6 +236,34 @@ fresh_perl_is
{ stderr => 1 },
"Assigning a nameless package over one w/subclasses updates isa caches";
+# mro_package_moved needs to make a distinction between replaced and
+# assigned stashes when keeping track of what it has seen so far.
+no warnings; {
+ no strict 'refs';
+
+ sub bar::blonk::blonk::phoo { "bbb" }
+ sub veclum::phoo { "lasrevinu" }
+ @feedlebomp::ISA = qw 'phoo::blonk::blonk veclum';
+ *phoo::baz:: = *bar::blonk::; # now bar::blonk:: is on both sides
+ *phoo:: = *bar::; # here bar::blonk:: is both deleted and added
+ *bar:: = *boo::; # now it is only known as phoo::blonk::
+
+ # At this point, before the bug was fixed, %phoo::blonk::blonk:: ended
+ # up with no effective name, allowing it to be deleted without updating
+ # its subclasses’ caches.
+
+ my $accum = '';
+
+ $accum .= 'feedlebomp'->phoo; # bbb
+ delete ${"phoo::blonk::"}{"blonk::"};
+ $accum .= 'feedlebomp'->phoo; # bbb (Oops!)
+ @feedlebomp::ISA = @feedlebomp::ISA;
+ $accum .= 'feedlebomp'->phoo; # lasrevinu
+
+ is $accum, 'bbblasrevinulasrevinu',
+ 'nested classes deleted & added simultaneously';
+}
+use warnings;
# mro_package_moved needs to check for self-referential packages.
# This broke Text::Template [perl #78362].