4 use open qw( :utf8 :std );
8 BEGIN { require q(./test.pl); } plan(tests => 53);
20 our @ISA = qw/MRO_அ MRO_ɓ MRO_ᶝ/;
22 our @ISA = qw/MRO_அ MRO_ɓ MRO_ᶝ/;
24 our @ISA = qw/MRO_d MRO_ɛ/;
27 my @MFO_ᚠ_DFS = qw/MRO_ᚠ MRO_d MRO_அ MRO_ɓ MRO_ᶝ MRO_ɛ/;
28 my @MFO_ᚠ_C3 = qw/MRO_ᚠ MRO_d MRO_ɛ MRO_அ MRO_ɓ MRO_ᶝ/;
29 is(mro::get_mro('MRO_ᚠ'), 'dfs');
31 mro::get_linear_isa('MRO_ᚠ'), \@MFO_ᚠ_DFS
34 ok(eq_array(mro::get_linear_isa('MRO_ᚠ', 'dfs'), \@MFO_ᚠ_DFS));
35 ok(eq_array(mro::get_linear_isa('MRO_ᚠ', 'c3'), \@MFO_ᚠ_C3));
36 eval{mro::get_linear_isa('MRO_ᚠ', 'C3')};
37 like($@, qr/^Invalid mro name: 'C3'/);
39 mro::set_mro('MRO_ᚠ', 'c3');
40 is(mro::get_mro('MRO_ᚠ'), 'c3');
42 mro::get_linear_isa('MRO_ᚠ'), \@MFO_ᚠ_C3
45 ok(eq_array(mro::get_linear_isa('MRO_ᚠ', 'dfs'), \@MFO_ᚠ_DFS));
46 ok(eq_array(mro::get_linear_isa('MRO_ᚠ', 'c3'), \@MFO_ᚠ_C3));
47 eval{mro::get_linear_isa('MRO_ᚠ', 'C3')};
48 like($@, qr/^Invalid mro name: 'C3'/);
50 ok(!mro::is_universal('MRO_ɓ'));
52 @UNIVERSAL::ISA = qw/MRO_ᚠ/;
53 ok(mro::is_universal('MRO_ɓ'));
56 ok(!mro::is_universal('MRO_ᚠ'));
57 ok(!mro::is_universal('MRO_ɓ'));
59 # is_universal, get_mro, and get_linear_isa should
60 # handle non-existent packages sanely
61 ok(!mro::is_universal('Does_Not_Exist'));
62 is(mro::get_mro('Also_Does_Not_Exist'), 'dfs');
64 mro::get_linear_isa('Does_Not_Exist_Three'),
65 [qw/Does_Not_Exist_Three/]
68 # Assigning @ISA via globref
71 sub 텟tf운ꜿ { return 123 }
72 package MRO_Test옽ḦРꤷsӭ;
73 sub 텟ₜꖢᶯcƧ { return 321 }
74 package MRO_Ɯ; our @ISA = qw/MRO_ҭṣṱबꗻ/;
76 *MRO_ᕡ::ISA = *MRO_Ɯ::ISA;
77 is(eval { MRO_ᕡ->텟tf운ꜿ() }, 123);
79 # XXX TODO (when there's a way to backtrack through a glob's aliases)
80 # push(@MRO_M::ISA, 'MRO_TestOtherBase');
81 # is(eval { MRO_N->testfunctwo() }, 321);
83 # Simple DESTROY Baseline
89 package DESTROY_MRO_Bӓeᓕne;
90 sub new { bless {} => shift }
93 package DESTROY_MRO_Bӓeᓕne_χḻɖ;
94 our @ISA = qw/DESTROY_MRO_Bӓeᓕne/;
97 $obj = DESTROY_MRO_Bӓeᓕne->new();
101 $obj = DESTROY_MRO_Bӓeᓕne_χḻɖ->new();
112 package DESTROY_MRO_Dჷ및;
113 sub new { bless {} => shift }
115 package DESTROY_MRO_Dჷ및_χḻɖ;
116 our @ISA = qw/DESTROY_MRO_Dჷ및/;
119 $obj = DESTROY_MRO_Dჷ및->new();
123 $obj = DESTROY_MRO_Dჷ및_χḻɖ->new();
128 *DESTROY_MRO_Dჷ및::DESTROY = sub { $x++ };
130 $obj = DESTROY_MRO_Dჷ및->new();
134 $obj = DESTROY_MRO_Dჷ및_χḻɖ->new();
139 # clearing @ISA in different ways
140 # some are destructive to the package, hence the new
141 # package name each time
143 no warnings 'uninitialized';
146 our @ISA = qw/xx ƳƳ ƶƶ/;
149 ok(eq_array(mro::get_linear_isa('ᛁ앛ଌᛠ'),[qw/ᛁ앛ଌᛠ xx ƳƳ ƶƶ/]));
151 # this looks dumb, but it preserves existing behavior for compatibility
152 # (undefined @ISA elements treated as "main")
153 $ᛁ앛ଌᛠ::ISA[1] = undef;
154 ok(eq_array(mro::get_linear_isa('ᛁ앛ଌᛠ'),[qw/ᛁ앛ଌᛠ xx main ƶƶ/]));
156 # undef the array itself
158 ok(eq_array(mro::get_linear_isa('ᛁ앛ଌᛠ'),[qw/ᛁ앛ଌᛠ/]));
160 # Now, clear more than one package's @ISA at once
163 our @ISA = qw/WẆ xx/;
166 our @ISA = qw/ƳƳ ƶƶ/;
169 ok(eq_array(mro::get_linear_isa('ᛁ앛ଌᛠ1'),[qw/ᛁ앛ଌᛠ1 WẆ xx/]));
170 ok(eq_array(mro::get_linear_isa('ᛁ앛ଌᛠ2'),[qw/ᛁ앛ଌᛠ2 ƳƳ ƶƶ/]));
171 (@ᛁ앛ଌᛠ1::ISA, @ᛁ앛ଌᛠ2::ISA) = ();
173 ok(eq_array(mro::get_linear_isa('ᛁ앛ଌᛠ1'),[qw/ᛁ앛ଌᛠ1/]));
174 ok(eq_array(mro::get_linear_isa('ᛁ앛ଌᛠ2'),[qw/ᛁ앛ଌᛠ2/]));
176 # [perl #49564] This is a pretty obscure way of clearing @ISA but
177 # it tests a regression that affects XS code calling av_clear too.
180 our @ISA = qw/WẆ xx/;
182 ok(eq_array(mro::get_linear_isa('ᛁ앛ଌᛠ3'),[qw/ᛁ앛ଌᛠ3 WẆ xx/]));
187 ok(eq_array(mro::get_linear_isa('ᛁ앛ଌᛠ3'),[qw/ᛁ앛ଌᛠ3/]));
190 # Check that recursion bails out "cleanly" in a variety of cases
191 # (as opposed to say, bombing the interpreter or something)
193 my @recurse_codes = (
194 '@MRO_ഋ1::ISA = "MRO_ഋ2"; @MRO_ഋ2::ISA = "MRO_ഋ1";',
195 '@MRO_ഋ3::ISA = "MRO_ഋ4"; push(@MRO_ഋ4::ISA, "MRO_ഋ3");',
196 '@MRO_ഋ5::ISA = "MRO_ഋ6"; @MRO_ഋ6::ISA = qw/xx MRO_ഋ5 ƳƳ/;',
197 '@MRO_ഋ7::ISA = "MRO_ഋ8"; push(@MRO_ഋ8::ISA, qw/xx MRO_ഋ7 ƳƳ/)',
199 foreach my $code (@recurse_codes) {
201 ok($@ =~ /Recursive inheritance detected/);
205 # Check that SUPER caches get invalidated correctly
209 sub new { bless {} => shift }
216 our @ISA = 'スṔઍR텟ʇ::MᶤƉ';
217 sub ຟઓ { my $s = shift; $s->SUPER::ຟઓ(@_) }
223 my $stk_obj = スṔઍR텟ʇ::킫->new();
224 is($stk_obj->ຟઓ(1), 2);
225 { no warnings 'redefine';
226 *スṔઍR텟ʇ::ຟઓ = sub { $_[1]+2 };
228 is($stk_obj->ຟઓ(2), 4);
229 @スṔઍR텟ʇ::MᶤƉ::ISA = 'スṔઍR텟ʇ::렙ﷰए';
230 is($stk_obj->ຟઓ(3), 6);
235 # assigning @ISA via arrayref to globref RT 60220
237 sub new { bless {}, shift }
241 *{ᛔ2::ISA} = [ 'ᛔ1' ];
243 ok(!eval { $foo->ɓᛅƘ }, "no ɓᛅƘ method");
244 no warnings 'once'; # otherwise it'll bark about ᛔ1::ɓᛅƘ used only once
245 *{ᛔ1::ɓᛅƘ} = sub { "[ɓᛅƘ]" };
246 is(scalar eval { $foo->ɓᛅƘ }, "[ɓᛅƘ]", "can ɓᛅƘ now");
251 # assigning @ISA via arrayref then modifying it RT 72866
269 ok(!ㄑ3->can("Fஓ"), "can't call Fஓ method any longer");
273 # test mro::method_changed_in
274 my $count = mro::get_pkg_gen("MRO_அ");
275 mro::method_changed_in("MRO_அ");
276 my $count_new = mro::get_pkg_gen("MRO_அ");
278 is($count_new, $count + 1);
282 # test if we can call mro::invalidate_all_method_caches;
284 mro::invalidate_all_method_caches();
292 @main::ISA = 'პᛅeȵᛏ';
294 *პᛅeȵᛏ::ど = sub { $output .= 'პᛅeȵᛏ' };
295 *პᛅeȵᛏ2::ど = sub { $output .= 'პᛅeȵᛏ2' };
297 @main::ISA = 'პᛅeȵᛏ2';
299 is $output, 'პᛅeȵᛏპᛅeȵᛏ2', '@main::ISA is magical';
303 # Undefining *ISA, then modifying @ISA
304 # This broke Class::Trait. See [perl #79024].
305 {package Class::Trait::Base}
307 undef *{"एxṰர::ʦፖㄡsȨ::ISA"};
308 'एxṰர::ʦፖㄡsȨ'->isa('Class::Trait::Base'); # cache the mro
309 unshift @{"एxṰர::ʦፖㄡsȨ::ISA"}, 'Class::Trait::Base';
310 ok 'एxṰர::ʦፖㄡsȨ'->isa('Class::Trait::Base'),
311 'a isa b after undef *a::ISA and @a::ISA modification';
315 # Deleting $package::{ISA}
316 # Broken in 5.10.0; fixed in 5.13.7
317 @BḼᵑth::ISA = 'Bલdḏ';
318 delete $BḼᵑth::{ISA};
319 ok !BḼᵑth->isa("Bલdḏ"), 'delete $package::{ISA}';
327 ok !ᖫᕃㄒṭ->isa('ሲঌએ'), 'undef %package:: updates subclasses';