4 $ENV{PERL_UNICODE} = 0;
15 use open qw( :utf8 :std );
30 *{'ऑlㄉ::'} = *{'Neẁ::'};
34 ok (ऑlㄉ->isa(Neẁ::), 'ऑlㄉ inherits from Neẁ');
35 ok (Neẁ->isa(ऑlㄉ::), 'Neẁ inherits from ऑlㄉ');
37 object_ok (bless ({}, ऑlㄉ::), Neẁ::, 'ऑlㄉ object');
38 object_ok (bless ({}, Neẁ::), ऑlㄉ::, 'Neẁ object');
41 # Test that replacing a package by assigning to an existing glob
42 # invalidates the isa caches
45 name => 'assigning a glob to a glob',
46 code => '$life_raft = $::{"lㅔf::"}; *lㅔf:: = $::{"릭Ⱶᵀ::"}',
49 name => 'assigning a string to a glob',
50 code => '$life_raft = $::{"lㅔf::"}; *lㅔf:: = "릭Ⱶᵀ::"',
53 name => 'assigning a stashref to a glob',
54 code => '$life_raft = \%lㅔf::; *lㅔf:: = \%릭Ⱶᵀ::',
65 use open qw( :utf8 :std );
70 sub 톺ĺФț::Sᑊeಅḱ { "Woof!" }
71 sub ᴖ릭ᚽʇ::Sᑊeಅḱ { "Bow-wow!" }
73 my $thing = bless [], "숩cਲꩋ";
75 # mro_package_moved needs to know to skip non-globs
76 $릭Ⱶᵀ::{"ᚷꝆエcƙ::"} = 3;
82 print $thing->Sᑊeಅḱ, "\n";
85 print $thing->Sᑊeಅḱ, "\n";
86 ~ =~ s\__code__\$$_{code}\r; #\
90 "Bow-wow!\nBow-wow!\n",
92 "replacing packages by $$_{name} updates isa caches";
95 # Similar test, but with nested packages
97 # 톺ĺФț (Woof) ᴖ릭ᚽʇ (Bow-wow)
99 # lㅔf::Side <- 릭Ⱶᵀ::Side
103 # This test assigns 릭Ⱶᵀ:: to lㅔf::, indirectly making lㅔf::Side an
104 # alias to 릭Ⱶᵀ::Side (following the arrow in the diagram).
107 name => 'assigning a glob to a glob',
108 code => '$life_raft = $::{"lㅔf::"}; *lㅔf:: = $::{"릭Ⱶᵀ::"}',
111 name => 'assigning a string to a glob',
112 code => '$life_raft = $::{"lㅔf::"}; *lㅔf:: = "릭Ⱶᵀ::"',
115 name => 'assigning a stashref to a glob',
116 code => '$life_raft = \%lㅔf::; *lㅔf:: = \%릭Ⱶᵀ::',
127 use open qw( :utf8 :std );
128 @숩cਲꩋ::ISA = "lㅔf::Side";
129 @lㅔf::Side::ISA = "톺ĺФț";
131 sub 톺ĺФț::Sᑊeಅḱ { "Woof!" }
132 sub ᴖ릭ᚽʇ::Sᑊeಅḱ { "Bow-wow!" }
134 my $thing = bless [], "숩cਲꩋ";
136 @릭Ⱶᵀ::Side::ISA = 'ᴖ릭ᚽʇ';
140 print $thing->Sᑊeಅḱ, "\n";
143 print $thing->Sᑊeಅḱ, "\n";
144 ~ =~ s\__code__\$$_{code}\r;
149 "Bow-wow!\nBow-wow!\n",
151 "replacing nested packages by $$_{name} updates isa caches";
154 # Another nested package test, in which the isa cache needs to be reset on
155 # the subclass of a package that does not exist.
157 # Parenthesized packages do not exist.
159 # ɵűʇㄦ::인ንʵ ( cฬnए::인ንʵ )
165 # This test assigns ɵűʇㄦ:: to cฬnए::, making cฬnए::인ንʵ an alias to
168 # Then we also run the test again, but without ɵűʇㄦ::인ንʵ
171 name => 'assigning a glob to a glob',
172 code => '*cฬnए:: = *ɵűʇㄦ::',
175 name => 'assigning a string to a glob',
176 code => '*cฬnए:: = "ɵűʇㄦ::"',
179 name => 'assigning a stashref to a glob',
180 code => '*cฬnए:: = \%ɵűʇㄦ::',
183 for my $tail ('인ንʵ', '인ንʵ::', '인ንʵ:::', '인ንʵ::::') {
192 use open qw( :utf8 :std );
195 if (grep /\P{ASCII}/, @ARGV) {
196 @ARGV = map { Encode::decode("UTF-8", $_) } @ARGV;
200 @Lфť::ISA = "ɵűʇㄦ::$tail";
201 @R익hȚ::ISA = "cฬnए::$tail";
202 bless [], "ɵűʇㄦ::$tail"; # autovivify the stash
206 print "ok 1", "\n" if Lфť->isa("cฬnए::$tail");
207 print "ok 2", "\n" if R익hȚ->isa("ɵűʇㄦ::$tail");
208 print "ok 3", "\n" if R익hȚ->isa("cฬnए::$tail");
209 print "ok 4", "\n" if Lфť->isa("ɵűʇㄦ::$tail");
210 ~ =~ s\__code__\$$_{code}\r;
214 "ok 1\nok 2\nok 3\nok 4\n",
216 "replacing nonexistent nested packages by $$_{name} updates isa caches"
219 # Same test but with the subpackage autovivified after the assignment
228 use open qw( :utf8 :std );
231 if (grep /\P{ASCII}/, @ARGV) {
232 @ARGV = map { Encode::decode("UTF-8", $_) } @ARGV;
236 @Lфť::ISA = "ɵűʇㄦ::$tail";
237 @R익hȚ::ISA = "cฬnए::$tail";
241 bless [], "ɵűʇㄦ::$tail";
243 print "ok 1", "\n" if Lфť->isa("cฬnए::$tail");
244 print "ok 2", "\n" if R익hȚ->isa("ɵűʇㄦ::$tail");
245 print "ok 3", "\n" if R익hȚ->isa("cฬnए::$tail");
246 print "ok 4", "\n" if Lфť->isa("ɵűʇㄦ::$tail");
247 ~ =~ s\__code__\$$_{code}\r;
251 "ok 1\nok 2\nok 3\nok 4\n",
253 "Giving nonexistent packages multiple effective names by $$_{name}"
258 no warnings; # temporary; there seems to be a scoping bug, as this does not
259 # work when placed in the blocks below
261 # Test that deleting stash elements containing
262 # subpackages also invalidates the isa cache.
263 # Maybe this does not belong in package_aliases.t, but it is closely
264 # related to the tests immediately preceding.
266 @ቹऋ::ISA = ("Cuȓ", "ฮンᛞ");
267 @Cuȓ::ISA = "Hyḹ앛Ҭテ";
269 sub Hyḹ앛Ҭテ::Sᑊeಅḱ { "Arff!" }
270 sub ฮンᛞ::Sᑊeಅḱ { "Woof!" }
272 my $pet = bless [], "ቹऋ";
274 my $life_raft = delete $::{'Cuȓ::'};
276 is $pet->Sᑊeಅḱ, 'Woof!',
277 'deleting a stash from its parent stash invalidates the isa caches';
280 is $pet->Sᑊeಅḱ, 'Woof!',
281 'the deleted stash is gone completely when freed';
283 # Same thing, but with nested packages
285 @펱ᑦ::ISA = ("Cuȓȓ::Cuȓȓ::Cuȓȓ", "ɥwn");
286 @Cuȓȓ::Cuȓȓ::Cuȓȓ::ISA = "lȺt랕ᚖ";
288 sub lȺt랕ᚖ::Sᑊeಅḱ { "Arff!" }
289 sub ɥwn::Sᑊeಅḱ { "Woof!" }
291 my $pet = bless [], "펱ᑦ";
293 my $life_raft = delete $::{'Cuȓȓ::'};
295 is $pet->Sᑊeಅḱ, 'Woof!',
296 'deleting a stash from its parent stash resets caches of substashes';
299 is $pet->Sᑊeಅḱ, 'Woof!',
300 'the deleted substash is gone completely when freed';
304 my $prog = q~#!perl -w
312 use open qw( :utf8 :std );
316 sub Bᛆヶṝ::Sᑊeಅḱ { print "Woof!\n" }
317 sub lȺt랕ᚖ::Sᑊeಅḱ { print "Bow-wow!\n" }
319 my $pet = bless [], "펱ᑦ";
323 sub ດƓ::Sᑊeಅḱ { print "Hello.\n" } # strange ດƓ!
325 *T잌ዕ:: = delete $::{'ດƓ::'};
334 "Assigning a nameless package over one w/subclasses updates isa caches";
336 # mro_package_moved needs to make a distinction between replaced and
337 # assigned stashes when keeping track of what it has seen so far.
341 sub ʉ::bᓗnǩ::bᓗnǩ::ພo { "bbb" }
342 sub ᵛeↄl움::ພo { "lasrevinu" }
343 @ݏ엗Ƚeᵬૐᵖ::ISA = qw 'ພo::bᓗnǩ::bᓗnǩ ᵛeↄl움';
344 *ພo::ବㄗ:: = *ʉ::bᓗnǩ::; # now ʉ::bᓗnǩ:: is on both sides
345 *ພo:: = *ʉ::; # here ʉ::bᓗnǩ:: is both deleted and added
346 *ʉ:: = *ቦᵕ::; # now it is only known as ພo::bᓗnǩ::
348 # At this point, before the bug was fixed, %ພo::bᓗnǩ::bᓗnǩ:: ended
349 # up with no effective name, allowing it to be deleted without updating
350 # its subclassesâ
\80\99 caches.
354 $accum .= 'ݏ엗Ƚeᵬૐᵖ'->ພo; # bbb
355 delete ${"ພo::bᓗnǩ::"}{"bᓗnǩ::"};
356 $accum .= 'ݏ엗Ƚeᵬૐᵖ'->ພo; # bbb (Oops!)
357 @ݏ엗Ƚeᵬૐᵖ::ISA = @ݏ엗Ƚeᵬૐᵖ::ISA;
358 $accum .= 'ݏ엗Ƚeᵬૐᵖ'->ພo; # lasrevinu
360 is $accum, 'bbblasrevinulasrevinu',
361 'nested classes deleted & added simultaneously';
365 # mro_package_moved needs to check for self-referential packages.
366 # This broke Text::Template [perl #78362].
369 *Aᶜme::Mῌ::Aᶜme:: = \*Aᶜme::; # indirect self-reference
370 pass("mro_package_moved and self-referential packages");
372 # Deleting a glob whose name does not indicate its location in the symbol
373 # table but which nonetheless *is* in the symbol table.
377 @ოƐ::mഒrェ::ISA = "foᚒ";
378 sub foᚒ::ວmᑊ { "aoeaa" }
381 @C힐dᒡl았::ISA = 'ťວ::mഒrェ';
382 my $accum = 'C힐dᒡl았'->ວmᑊ . '-';
383 my $life_raft = delete ${"ťວ::"}{"mഒrェ::"};
384 $accum .= eval { 'C힐dᒡl았'->ວmᑊ } // '<undef>';
385 is $accum, 'aoeaa-<undef>',
386 'Deleting globs whose loc in the symtab differs from gv_fullname'
389 # Pathological test for undeffing a stash that has an alias.
393 sub F렐ᛔ::ວmᑊ { "clumpren" }
398 is eval { '숩cਲꩋ'->ວmᑊ }, 'clumpren',
399 'Changes to @ISA after undef via original name';
405 is eval { '숩cਲꩋ'->ວmᑊ }, 'clumpren',
406 'Changes to @ISA after undef via alias';
409 # Packages whose containing stashes have aliases must lose all names cor-
410 # responding to that container when detached.
412 {package śmᛅḙ::በɀ} # autovivify
413 *pḢ린ᚷ:: = *śmᛅḙ::; # śmᛅḙ::በɀ now also named pḢ린ᚷ::በɀ
414 *본:: = delete $śmᛅḙ::{"በɀ::"};
415 # In 5.13.7, it has now lost its śmᛅḙ::በɀ name (reverting to pḢ린ᚷ::በɀ
416 # as the effective name), and gained 본 as an alias.
417 # In 5.13.8, both śmᛅḙ::በɀ *and* pḢ린ᚷ::በɀ names are deleted.
421 *{"pḢ린ᚷ::በɀ::fฤmᛈ"} = sub { "hello" };
422 sub Fルmፕṟ::fฤmᛈ { "good bye" };
424 @ᵇるᣘ킨::ISA = qw "본 Fルmፕṟ"; # now wrongly inherits from pḢ린ᚷ::በɀ
426 is fฤmᛈ ᵇるᣘ킨, "good bye",
427 'detached stashes lose all names corresponding to the containing stash';
430 # Crazy edge cases involving packages ending with a single :
431 @촐oン::ISA = 'ᚖგ:'; # pun intended!
432 bless [], "ᚖგ:"; # autovivify the stash
433 ok "촐oン"->isa("ᚖგ:"), 'class isa "class:"';
434 { no strict 'refs'; *{"ᚖგ:::"} = *ᚖგ:: }
436 'isa(ᕘ) when inheriting from "class:" which is an alias for ᕘ';
439 # The next line of code is *not* normative. If the structure changes,
440 # this line needs to change, too.
441 my $ᕘ = delete $ᚖგ::{":"};
443 'class that isa "class:" no longer isa ᕘ if "class:" has been deleted';
447 ok "촐oン"->isa(":"), 'class isa ":"';
448 { no strict 'refs'; *{":::"} = *ፑňṪu앝ȋ온:: }
449 ok "촐oン"->isa("ፑňṪu앝ȋ온"),
450 'isa(ᕘ) when inheriting from ":" which is an alias for ᕘ';
455 my $life_raft = \%{"ᚖგ:::"};
458 'isa(ᕘ) when inheriting from "class:" after hash-to-glob assignment';
464 my $life_raft = \%{"ŏ:::"};
467 'isa(ᕘ) when inheriting from "class:" after string-to-glob assignment';