xref: /openbsd/gnu/usr.bin/perl/t/uni/stash.t (revision 264ca280)
1#!./perl
2
3#
4# various stash tests
5#
6
7BEGIN {
8    chdir 't' if -d 't';
9    @INC = '../lib';
10    require './test.pl';
11}
12
13use utf8;
14use open qw( :utf8 :std );
15
16plan( tests => 58 );
17
18#These come from op/my_stash.t
19{
20    use constant Myクラス => 'ꕽ::Ʉ::ꔬz::ꢨᙇ';
21
22    {
23        package ꕽ::Ʉ::ꔬz::ꢨᙇ;
24        1;
25    }
26
27    for (qw(ꕽ ꕽ:: Myクラス __PACKAGE__)) {
28        eval "sub { my $_ \$obj = shift; }";
29        ok ! $@, "op/my_stash.t test, $_";
30    }
31
32    use constant NòClàss => '노pӬ::ꕽ::Ꜻ::BӢz::ʙࡆ';
33
34    for (qw(노pӬ 노pӬ:: NòClàss)) {
35        eval "sub { my $_ \$obj = shift; }";
36        ok $@, "op/my_stash.t test";
37    }
38}
39
40#op/stash.t
41{
42    {
43        no warnings 'deprecated';
44        ok( defined %왿ퟀⲺa::ᒫṡ::, q(stashes happen to be defined if not used) );
45        ok( defined %{"왿ퟀⲺa::ᒫṡ::"}, q(- work with hard refs too) );
46
47        ok( defined %ᛐⲞɲe::Šꇇᚽṙᆂṗ::, q(stashes are defined if seen at compile time) );
48        ok( defined %{"ᛐⲞɲe::Šꇇᚽṙᆂṗ::"}, q(- work with hard refs too) );
49
50        ok( defined %본go::ଶfʦbᚒƴ::, q(stashes are defined if a var is seen at compile time) );
51        ok( defined %{"본go::ଶfʦbᚒƴ::"}, q(- work with hard refs too) );
52    }
53
54
55    package ᛐⲞɲe::Šꇇᚽṙᆂṗ;
56    $본go::ଶfʦbᚒƴ::scalar = 1;
57
58    package main;
59
60    # now tests in eval
61
62    ok( eval  { no warnings 'deprecated'; defined %앛hȚꟻࡃҥ:: },   'works in eval{}' );
63    ok( eval q{ no warnings 'deprecated'; defined %Ṧㄘㇹen맠ㄦ:: }, 'works in eval("")' );
64
65    # now tests with strictures
66
67    {
68        use strict;
69        no warnings 'deprecated';
70        ok( defined %piƓ::, q(referencing a non-existent stash doesn't produce stricture errors) );
71        ok( !exists $piƓ::{bodine}, q(referencing a non-existent stash element doesn't produce stricture errors) );
72    }
73
74    SKIP: {
75        eval { require B; 1 } or skip "no B", 28;
76
77        *b = \&B::svref_2object;
78        my $CVf_ANON = B::CVf_ANON();
79
80        my $sub = do {
81            package 온ꪵ;
82            \&{"온ꪵ"};
83        };
84        delete $온ꪵ::{온ꪵ};
85        my $gv = b($sub)->GV;
86
87        object_ok( $gv, "B::GV", "deleted stash entry leaves CV with valid GV");
88        is( b($sub)->CvFLAGS & $CVf_ANON, $CVf_ANON, "...and CVf_ANON set");
89        is( eval { $gv->NAME }, "__ANON__", "...and an __ANON__ name");
90        is( eval { $gv->STASH->NAME }, "온ꪵ", "...but leaves stash intact");
91
92        $sub = do {
93            package tꖿ;
94            \&{"tꖿ"};
95        };
96        %tꖿ:: = ();
97        $gv = b($sub)->GV;
98
99        object_ok( $gv, "B::GV", "cleared stash leaves CV with valid GV");
100        is( b($sub)->CvFLAGS & $CVf_ANON, $CVf_ANON, "...and CVf_ANON set");
101        is( eval { $gv->NAME }, "__ANON__", "...and an __ANON__ name");
102        is( eval { $gv->STASH->NAME }, "tꖿ", "...but leaves stash intact");
103
104        $sub = do {
105            package ᖟ레ᅦ;
106            \&{"ᖟ레ᅦ"};
107        };
108        undef %ᖟ레ᅦ::;
109        $gv = b($sub)->GV;
110
111        object_ok( $gv, "B::GV", "undefed stash leaves CV with valid GV");
112        is( b($sub)->CvFLAGS & $CVf_ANON, $CVf_ANON, "...and CVf_ANON set");
113        is( eval { $gv->NAME }, "__ANON__", "...and an __ANON__ name");
114        is( eval { $gv->STASH->NAME }, "__ANON__", "...and an __ANON__ stash");
115
116        my $sub = do {
117            package ꃖᚢ;
118            sub { 1 };
119        };
120        %ꃖᚢ:: = ();
121
122        my $gv = B::svref_2object($sub)->GV;
123        ok($gv->isa(q/B::GV/), "cleared stash leaves anon CV with valid GV");
124
125        my $st = eval { $gv->STASH->NAME };
126        is($st, q/ꃖᚢ/, "...but leaves the stash intact");
127
128        $sub = do {
129            package fꢄᶹᵌ;
130            sub { 1 };
131        };
132        undef %fꢄᶹᵌ::;
133
134        $gv = B::svref_2object($sub)->GV;
135        ok($gv->isa(q/B::GV/), "undefed stash leaves anon CV with valid GV");
136
137        $st = eval { $gv->STASH->NAME };
138
139        { local $TODO = 'STASHES not anonymized';
140            is($st, q/__ANON__/, "...and an __ANON__ stash");
141        }
142
143        $sub = do {
144            package sӥㄒ;
145            \&{"sӥㄒ"}
146        };
147        my $stash_glob = delete $::{"sӥㄒ::"};
148        # Now free the GV while the stash still exists (though detached)
149        delete $$stash_glob{"sӥㄒ"};
150        $gv = B::svref_2object($sub)->GV;
151        ok($gv->isa(q/B::GV/),
152        'anonymised CV whose stash is detached still has a GV');
153        #fails because mro_gather_and_rename isn't clean
154        is $gv->STASH->NAME, '__ANON__',
155        'CV anonymised when its stash is detached becomes __ANON__::__ANON__';
156
157        # CvSTASH should be null on a named sub if the stash has been deleted
158        {
159            package FŌŌ;
160            sub Ƒಓ {}
161            my $rfoo = \&Ƒಓ;
162            package main;
163            delete $::{'FŌŌ::'};
164            my $cv = B::svref_2object($rfoo);
165            # (is there a better way of testing for NULL ?)
166            my $stash = $cv->STASH;
167            like($stash, qr/B::SPECIAL/, "NULL CvSTASH on named sub");
168        }
169
170        # on glob reassignment, orphaned CV should have anon CvGV
171
172        {
173            my $r;
174            eval q[
175                package FŌŌ௨;
176                sub Ƒ{};
177                $r = \&Ƒ;
178                *Ƒ = sub {};
179            ];
180            delete $FŌŌ௨::{Ƒ};
181            my $cv = B::svref_2object($r);
182            my $gv = $cv->GV;
183            ok($gv->isa(q/B::GV/), "orphaned CV has valid GV");
184            is($gv->NAME, '__ANON__', "orphaned CV has anon GV");
185        }
186
187        # deleting __ANON__ glob shouldn't break things
188
189        {
190            package FŌŌ3;
191            sub 남えㄉ {};
192            my $anon = sub {};
193            my $남えㄉ = eval q[\&남えㄉ];
194            package main;
195            delete $FŌŌ3::{남えㄉ}; # make named anonymous
196
197            delete $FŌŌ3::{__ANON__}; # whoops!
198            my ($cv,$gv);
199            $cv = B::svref_2object($남えㄉ);
200            $gv = $cv->GV;
201            ok($gv->isa(q/B::GV/), "ex-named CV has valid GV");
202            is($gv->NAME, '__ANON__', "ex-named CV has anon GV");
203
204            $cv = B::svref_2object($anon);
205            $gv = $cv->GV;
206            ok($gv->isa(q/B::GV/), "anon CV has valid GV");
207            is($gv->NAME, '__ANON__', "anon CV has anon GV");
208        }
209
210        {
211            my $r;
212            {
213                package bᓙṗ;
214
215                BEGIN {
216                    $r = \&main::Ẃⱒcᴷ;
217                }
218            }
219
220            my $br = B::svref_2object($r);
221            is ($br->STASH->NAME, 'bᓙṗ',
222                'stub records the package it was compiled in');
223
224            # We need to take this reference "late", after the subroutine is
225            # defined.
226            $br = B::svref_2object(eval 'sub Ẃⱒcᴷ {}; \&Ẃⱒcᴷ');
227            die $@ if $@;
228
229            is ($br->STASH->NAME, 'main',
230                'definition overrides the package it was compiled in');
231            like ($br->FILE, qr/eval/,
232                'definition overrides the file it was compiled in');
233        }
234    }
235
236    # make sure having a sub called __ANON__ doesn't confuse perl.
237
238    {
239        package クラス;
240        my $c;
241        sub __ANON__ { $c = (caller(0))[3]; }
242        {
243            local $@;
244            eval { ok(1); };
245            ::like($@, qr/^Undefined subroutine &クラス::ok/);
246        }
247        __ANON__();
248        ::is ($c, 'クラス::__ANON__', '__ANON__ sub called ok');
249    }
250
251    # Stashes that are effectively renamed
252    {
253        package rìle;
254
255        use Config;
256
257        my $obj  = bless [];
258        my $globref = \*tàt;
259
260        # effectively rename a stash
261        *slìn:: = *rìle::; *rìle:: = *zòr::;
262
263        ::is *$globref, "*rìle::tàt",
264        'globs stringify the same way when stashes are moved';
265        ::is ref $obj, "rìle",
266        'ref() returns the same thing when an object’s stash is moved';
267        ::like "$obj", qr "^rìle=ARRAY\(0x[\da-f]+\)\z",
268        'objects stringify the same way when their stashes are moved';
269        ::is eval '__PACKAGE__', 'rìle',
270            '__PACKAGE__ returns the same when the current stash is moved';
271
272        # Now detach it completely from the symtab, making it effect-
273        # ively anonymous
274        my $life_raft = \%slìn::;
275        *slìn:: = *zòr::;
276
277        ::is *$globref, "*rìle::tàt",
278        'globs stringify the same way when stashes are detached';
279        ::is ref $obj, "rìle",
280        'ref() returns the same thing when an object’s stash is detached';
281        ::like "$obj", qr "^rìle=ARRAY\(0x[\da-f]+\)\z",
282        'objects stringify the same way when their stashes are detached';
283        ::is eval '__PACKAGE__', 'rìle',
284            '__PACKAGE__ returns the same when the current stash is detached';
285    }
286
287    # Setting the name during undef %stash:: should have no effect.
288    {
289        my $glob = \*Phòò::glòb;
290        sub ò::DESTROY { eval '++$Phòò::bòr' }
291        no strict 'refs';
292        ${"Phòò::thòng1"} = bless [], "ò";
293        undef %Phòò::;
294        is "$$glob", "*__ANON__::glòb",
295        "setting stash name during undef has no effect";
296    }
297
298    # [perl #88134] incorrect package structure
299    {
300        package Bèàr::;
301        sub bàz{1}
302        package main;
303        ok eval { Bèàr::::bàz() },
304        'packages ending with :: are self-consistent';
305    }
306
307    # [perl #88138] ' not equivalent to :: before a null
308    ${"à'\0b"} = "c";
309    is ${"à::\0b"}, "c", "' is equivalent to :: before a null";
310}