#!./perl
BEGIN {
$ENV
{PERL_UNICODE} = 0;
unless
(-d
'blib'
) {
chdir
't'
if
-d
't'
;
}
require
q(./test.pl)
;
set_up_inc(
'../lib'
);
}
use
open
qw( :utf8 :std )
;
plan(
tests
=> 52);
{
package
Neẁ;
package
ऑlㄉ;
{
no
strict
'refs'
;
*{
'ऑlㄉ::'
} = *{
'Neẁ::'
};
}
}
ok (ऑlㄉ->isa(Neẁ::),
'ऑlㄉ inherits from Neẁ'
);
ok (Neẁ->isa(ऑlㄉ::),
'Neẁ inherits from ऑlㄉ'
);
object_ok (
bless
({}, ऑlㄉ::), Neẁ::,
'ऑlㄉ object'
);
object_ok (
bless
({}, Neẁ::), ऑlㄉ::,
'Neẁ object'
);
for
(
{
name
=>
'assigning a glob to a glob'
,
code
=>
'$life_raft = $::{"lㅔf::"}; *lㅔf:: = $::{"릭Ⱶᵀ::"}'
,
},
{
name
=>
'assigning a string to a glob'
,
code
=>
'$life_raft = $::{"lㅔf::"}; *lㅔf:: = "릭Ⱶᵀ::"'
,
},
{
name
=>
'assigning a stashref to a glob'
,
code
=>
'$life_raft = \%lㅔf::; *lㅔf:: = \%릭Ⱶᵀ::'
,
},
) {
my
$prog
=
q~
BEGIN {
unless (-d 'blib') {
chdir 't' if -d 't';
@INC = '../lib';
}
}
use utf8;
use open qw( :utf8 :std );
@숩cਲꩋ::ISA = "lㅔf";
@lㅔf::ISA = "톺ĺФț";
sub 톺ĺФț::Sᑊeಅḱ { "Woof!" }
sub ᴖ릭ᚽʇ::Sᑊeಅḱ { "Bow-wow!" }
my $thing = bless [], "숩cਲꩋ";
# mro_package_moved needs to know to skip non-globs
$릭Ⱶᵀ::{"ᚷꝆエcƙ::"} = 3;
@릭Ⱶᵀ::ISA = 'ᴖ릭ᚽʇ';
my $life_raft;
__code__;
print $thing->Sᑊeಅḱ, "\n";
undef $life_raft;
print $thing->Sᑊeಅḱ, "\n";
~
=~ s\__code__\
$$_
{code}\r;
utf8::encode(
$prog
);
fresh_perl_is
$prog
,
"Bow-wow!\nBow-wow!\n"
,
{},
"replacing packages by $$_{name} updates isa caches"
;
}
for
(
{
name
=>
'assigning a glob to a glob'
,
code
=>
'$life_raft = $::{"lㅔf::"}; *lㅔf:: = $::{"릭Ⱶᵀ::"}'
,
},
{
name
=>
'assigning a string to a glob'
,
code
=>
'$life_raft = $::{"lㅔf::"}; *lㅔf:: = "릭Ⱶᵀ::"'
,
},
{
name
=>
'assigning a stashref to a glob'
,
code
=>
'$life_raft = \%lㅔf::; *lㅔf:: = \%릭Ⱶᵀ::'
,
},
) {
my
$prog
=
q~
BEGIN {
unless (-d 'blib') {
chdir 't' if -d 't';
@INC = '../lib';
}
}
use utf8;
use open qw( :utf8 :std );
@숩cਲꩋ::ISA = "lㅔf::Side";
@lㅔf::Side::ISA = "톺ĺФț";
sub 톺ĺФț::Sᑊeಅḱ { "Woof!" }
sub ᴖ릭ᚽʇ::Sᑊeಅḱ { "Bow-wow!" }
my $thing = bless [], "숩cਲꩋ";
@릭Ⱶᵀ::Side::ISA = 'ᴖ릭ᚽʇ';
my $life_raft;
__code__;
print $thing->Sᑊeಅḱ, "\n";
undef $life_raft;
print $thing->Sᑊeಅḱ, "\n";
~
=~ s\__code__\
$$_
{code}\r;
utf8::encode(
$prog
);
fresh_perl_is
$prog
,
"Bow-wow!\nBow-wow!\n"
,
{},
"replacing nested packages by $$_{name} updates isa caches"
;
}
for
(
{
name
=>
'assigning a glob to a glob'
,
code
=>
'*cฬnए:: = *ɵűʇㄦ::'
,
},
{
name
=>
'assigning a string to a glob'
,
code
=>
'*cฬnए:: = "ɵűʇㄦ::"'
,
},
{
name
=>
'assigning a stashref to a glob'
,
code
=>
'*cฬnए:: = \%ɵűʇㄦ::'
,
},
) {
for
my
$tail
(
'인ንʵ'
,
'인ንʵ::'
,
'인ንʵ:::'
,
'인ንʵ::::'
) {
my
$prog
=
q~
BEGIN {
unless (-d 'blib') {
chdir 't' if -d 't';
@INC = '../lib';
}
}
use utf8;
use open qw( :utf8 :std );
use Encode ();
if (grep /\P{ASCII}/, @ARGV) {
@ARGV = map { Encode::decode("UTF-8", $_) } @ARGV;
}
my $tail = shift;
@Lфť::ISA = "ɵűʇㄦ::$tail";
@R익hȚ::ISA = "cฬnए::$tail";
bless [], "ɵűʇㄦ::$tail"; # autovivify the stash
__code__;
print "ok 1", "\n" if Lфť->isa("cฬnए::$tail");
print "ok 2", "\n" if R익hȚ->isa("ɵűʇㄦ::$tail");
print "ok 3", "\n" if R익hȚ->isa("cฬnए::$tail");
print "ok 4", "\n" if Lфť->isa("ɵűʇㄦ::$tail");
~
=~ s\__code__\
$$_
{code}\r;
utf8::encode(
$prog
);
fresh_perl_is
$prog
,
"ok 1\nok 2\nok 3\nok 4\n"
,
{
args
=> [
$tail
] },
"replacing nonexistent nested packages by $$_{name} updates isa caches"
.
" ($tail)"
;
$prog
=
q~
BEGIN {
unless (-d 'blib') {
chdir 't' if -d 't';
@INC = '../lib';
}
}
use utf8;
use open qw( :utf8 :std );
use Encode ();
if (grep /\P{ASCII}/, @ARGV) {
@ARGV = map { Encode::decode("UTF-8", $_) } @ARGV;
}
my $tail = shift;
@Lфť::ISA = "ɵűʇㄦ::$tail";
@R익hȚ::ISA = "cฬnए::$tail";
__code__;
bless [], "ɵűʇㄦ::$tail";
print "ok 1", "\n" if Lфť->isa("cฬnए::$tail");
print "ok 2", "\n" if R익hȚ->isa("ɵűʇㄦ::$tail");
print "ok 3", "\n" if R익hȚ->isa("cฬnए::$tail");
print "ok 4", "\n" if Lфť->isa("ɵűʇㄦ::$tail");
~
=~ s\__code__\
$$_
{code}\r;
utf8::encode(
$prog
);
fresh_perl_is
$prog
,
"ok 1\nok 2\nok 3\nok 4\n"
,
{
args
=> [
$tail
] },
"Giving nonexistent packages multiple effective names by $$_{name}"
.
" ($tail)"
;
}
}
no
warnings;
{
@ቹऋ::ISA = (
"Cuȓ"
,
"ฮンᛞ"
);
@Cu
ȓ::ISA =
"Hyḹ앛Ҭテ"
;
sub
Hyḹ앛Ҭテ::Sᑊeಅḱ {
"Arff!"
}
sub
ฮンᛞ::Sᑊeಅḱ {
"Woof!"
}
my
$pet
=
bless
[],
"ቹऋ"
;
my
$life_raft
=
delete
$::{
'Cuȓ::'
};
is
$pet
->Sᑊeಅḱ,
'Woof!'
,
'deleting a stash from its parent stash invalidates the isa caches'
;
undef
$life_raft
;
is
$pet
->Sᑊeಅḱ,
'Woof!'
,
'the deleted stash is gone completely when freed'
;
}
{
@펱ᑦ::ISA = (
"Cuȓȓ::Cuȓȓ::Cuȓȓ"
,
"ɥwn"
);
@Cu
ȓȓ::Cuȓȓ::Cuȓȓ::ISA =
"lȺt랕ᚖ"
;
sub
lȺt랕ᚖ::Sᑊeಅḱ {
"Arff!"
}
sub
ɥwn::Sᑊeಅḱ {
"Woof!"
}
my
$pet
=
bless
[],
"펱ᑦ"
;
my
$life_raft
=
delete
$::{
'Cuȓȓ::'
};
is
$pet
->Sᑊeಅḱ,
'Woof!'
,
'deleting a stash from its parent stash resets caches of substashes'
;
undef
$life_raft
;
is
$pet
->Sᑊeಅḱ,
'Woof!'
,
'the deleted substash is gone completely when freed'
;
}
my
$prog
=
q~#!perl -w
BEGIN {
unless (-d 'blib') {
chdir 't' if -d 't';
@INC = '../lib';
}
}
use utf8;
use open qw( :utf8 :std );
@펱ᑦ::ISA = "T잌ዕ";
@T잌ዕ::ISA = "Bᛆヶṝ";
sub Bᛆヶṝ::Sᑊeಅḱ { print "Woof!\n" }
sub lȺt랕ᚖ::Sᑊeಅḱ { print "Bow-wow!\n" }
my $pet = bless [], "펱ᑦ";
$pet->Sᑊeಅḱ;
sub ດƓ::Sᑊeಅḱ { print "Hello.\n" } # strange ດƓ!
@ດƓ::ISA = 'lȺt랕ᚖ';
*T잌ዕ:: = delete $::{'ດƓ::'};
$pet->Sᑊeಅḱ;
~
;
utf8::encode(
$prog
);
fresh_perl_is
$prog
,
"Woof!\nHello.\n"
,
{
stderr
=> 1 },
"Assigning a nameless package over one w/subclasses updates isa caches"
;
no
warnings; {
no
strict
'refs'
;
sub
ʉ::bᓗnǩ::bᓗnǩ::ພo {
"bbb"
}
sub
ᵛeↄl움::ພo {
"lasrevinu"
}
@ݏ엗Ƚeᵬૐᵖ::ISA =
qw 'ພo::bᓗnǩ::bᓗnǩ
ᵛeↄl움';
*ພo::ବㄗ:: = *ʉ::bᓗnǩ::;
*ພo:: = *ʉ::;
*ʉ:: = *ቦᵕ::;
my
$accum
=
''
;
$accum
.=
'ݏ엗Ƚeᵬૐᵖ'
->ພo;
delete
${
"ພo::bᓗnǩ::"
}{
"bᓗnǩ::"
};
$accum
.=
'ݏ엗Ƚeᵬૐᵖ'
->ພo;
@ݏ엗Ƚeᵬૐᵖ::ISA = @ݏ엗Ƚeᵬૐᵖ::ISA;
$accum
.=
'ݏ엗Ƚeᵬૐᵖ'
->ພo;
is
$accum
,
'bbblasrevinulasrevinu'
,
'nested classes deleted & added simultaneously'
;
}
watchdog 3;
*ᕘ:: = \%::;
*A
ᶜme::Mῌ::Aᶜme:: = \
*A
ᶜme::;
pass(
"mro_package_moved and self-referential packages"
);
{
no
strict
refs
=>;
no
warnings;
@ოƐ::mഒrェ::ISA =
"foᚒ"
;
sub
foᚒ::ວmᑊ {
"aoeaa"
}
*ťວ:: = *ოƐ::;
delete
$::{
"ოƐ::"
};
@C
힐dᒡl았::ISA =
'ťວ::mഒrェ'
;
my
$accum
=
'C힐dᒡl았'
->ວmᑊ .
'-'
;
my
$life_raft
=
delete
${
"ťວ::"
}{
"mഒrェ::"
};
$accum
.=
eval
{
'C힐dᒡl았'
->ວmᑊ } //
'<undef>'
;
is
$accum
,
'aoeaa-<undef>'
,
'Deleting globs whose loc in the symtab differs from gv_fullname'
}
*ᵍh엞:: = *ኔƞ::;
@숩cਲꩋ::ISA =
'ᵍh엞'
;
undef
%ᵍh엞::;
sub
F렐ᛔ::ວmᑊ {
"clumpren"
}
eval
'
$ኔƞ::whatever++;
@ኔƞ::ISA =
"F렐ᛔ"
;
';
is
eval
{
'숩cਲꩋ'
->ວmᑊ },
'clumpren'
,
'Changes to @ISA after undef via original name'
;
undef
%ᵍh엞::;
eval
'
$ᵍh엞::whatever++;
@ᵍh엞::ISA =
"F렐ᛔ"
;
';
is
eval
{
'숩cਲꩋ'
->ວmᑊ },
'clumpren'
,
'Changes to @ISA after undef via alias'
;
{
{
package
śmᛅḙ::በɀ}
*p
Ḣ린ᚷ:: = *śmᛅḙ::;
*본:: =
delete
$śmᛅḙ::{
"በɀ::"
};
no
strict
'refs'
;
*{
"pḢ린ᚷ::በɀ::fฤmᛈ"
} =
sub
{
"hello"
};
sub
Fルmፕṟ::fฤmᛈ {
"good bye"
};
@ᵇるᣘ킨::ISA =
qw "본
Fルmፕṟ";
is fฤmᛈ ᵇるᣘ킨,
"good bye"
,
'detached stashes lose all names corresponding to the containing stash'
;
}
@촐oン::ISA =
'ᚖგ:'
;
bless
[],
"ᚖგ:"
;
ok
"촐oン"
->isa(
"ᚖგ:"
),
'class isa "class:"'
;
{
no
strict
'refs'
; *{
"ᚖგ:::"
} = *ᚖგ:: }
ok
"촐oン"
->isa(
"ᚖგ"
),
'isa(ᕘ) when inheriting from "class:" which is an alias for ᕘ'
;
{
no
warnings;
my
$ᕘ =
delete
$ᚖგ::{
":"
};
ok !촐oン->isa(
"ᚖგ"
),
'class that isa "class:" no longer isa ᕘ if "class:" has been deleted'
;
}
@촐oン::ISA =
':'
;
bless
[],
":"
;
ok
"촐oン"
->isa(
":"
),
'class isa ":"'
;
{
no
strict
'refs'
; *{
":::"
} = *ፑňṪu앝ȋ온:: }
ok
"촐oン"
->isa(
"ፑňṪu앝ȋ온"
),
'isa(ᕘ) when inheriting from ":" which is an alias for ᕘ'
;
@촐oン::ISA =
'ᚖგ:'
;
bless
[],
"ᚖგ:"
;
{
no
strict
'refs'
;
my
$life_raft
= \%{
"ᚖგ:::"
};
*{
"ᚖგ:::"
} = \%ᚖგ::;
ok
"촐oン"
->isa(
"ᚖგ"
),
'isa(ᕘ) when inheriting from "class:" after hash-to-glob assignment'
;
}
@촐oン::ISA =
'ŏ:'
;
bless
[],
"ŏ:"
;
{
no
strict
'refs'
;
my
$life_raft
= \%{
"ŏ:::"
};
*{
"ŏ:::"
} =
"ᚖგ::"
;
ok
"촐oン"
->isa(
"ᚖგ"
),
'isa(ᕘ) when inheriting from "class:" after string-to-glob assignment'
;
}
=cut