This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Localising hash slices with UTF-8 encoded keys was also buggy.
[perl5.git] / t / op / ref.t
CommitLineData
79072805
LW
1#!./perl
2
20274adc
JH
3BEGIN {
4 chdir 't' if -d 't';
b5fe401b 5 @INC = qw(. ../lib);
20274adc
JH
6}
7
b2ce0fda 8require 'test.pl';
e24631be 9use strict qw(refs subs);
79072805 10
cbae9b9f 11plan(102);
805232b4 12
79072805
LW
13# Test glob operations.
14
1c509eb9
NC
15$bar = "one";
16$foo = "two";
79072805
LW
17{
18 local(*foo) = *bar;
1c509eb9 19 is($foo, 'one');
79072805 20}
1c509eb9 21is ($foo, 'two');
79072805 22
1c509eb9
NC
23$baz = "three";
24$foo = "four";
79072805
LW
25{
26 local(*foo) = 'baz';
1c509eb9 27 is ($foo, 'three');
79072805 28}
1c509eb9 29is ($foo, 'four');
79072805 30
1c509eb9 31$foo = "global";
79072805
LW
32{
33 local(*foo);
1c509eb9
NC
34 is ($foo, undef);
35 $foo = "local";
36 is ($foo, 'local');
79072805 37}
1c509eb9 38is ($foo, 'global');
79072805 39
e24631be
NC
40{
41 no strict 'refs';
79072805
LW
42# Test fake references.
43
e24631be
NC
44 $baz = "valid";
45 $bar = 'baz';
46 $foo = 'bar';
47 is ($$$foo, 'valid');
48}
79072805
LW
49
50# Test real references.
51
52$FOO = \$BAR;
53$BAR = \$BAZ;
1c509eb9
NC
54$BAZ = "hit";
55is ($$$FOO, 'hit');
79072805 56
05f9f7bb
JP
57# test that ref(vstring) makes sense
58my $vstref = \v1;
59is (ref($vstref), "VSTRING", "ref(vstr) eq VSTRING");
60like ( $vstref, qr/VSTRING\(0x[0-9a-f]+\)/, '\vstr is also VSTRING');
61
79072805
LW
62# Test references to real arrays.
63
1c509eb9
NC
64my $test = curr_test();
65@ary = ($test,$test+1,$test+2,$test+3);
79072805
LW
66$ref[0] = \@a;
67$ref[1] = \@b;
68$ref[2] = \@c;
69$ref[3] = \@d;
70for $i (3,1,2,0) {
71 push(@{$ref[$i]}, "ok $ary[$i]\n");
72}
73print @a;
74print ${$ref[1]}[0];
75print @{$ref[2]}[0];
e24631be
NC
76{
77 no strict 'refs';
78 print @{'d'};
79}
1c509eb9 80curr_test($test+4);
79072805
LW
81
82# Test references to references.
83
84$refref = \\$x;
1c509eb9
NC
85$x = "Good";
86is ($$$refref, 'Good');
79072805
LW
87
88# Test nested anonymous lists.
89
90$ref = [[],2,[3,4,5,]];
1c509eb9
NC
91is (scalar @$ref, 3);
92is ($$ref[1], 2);
93is (${$$ref[2]}[2], 5);
94is (scalar @{$$ref[0]}, 0);
79072805 95
1c509eb9
NC
96is ($ref->[1], 2);
97is ($ref->[2]->[0], 3);
79072805
LW
98
99# Test references to hashes of references.
100
101$refref = \%whatever;
102$refref->{"key"} = $ref;
1c509eb9 103is ($refref->{"key"}->[2]->[0], 3);
79072805 104
93a17b20 105# Test to see if anonymous subarrays spring into existence.
79072805
LW
106
107$spring[5]->[0] = 123;
108$spring[5]->[1] = 456;
109push(@{$spring[5]}, 789);
1c509eb9 110is (join(':',@{$spring[5]}), "123:456:789");
79072805 111
93a17b20 112# Test to see if anonymous subhashes spring into existence.
79072805
LW
113
114@{$spring2{"foo"}} = (1,2,3);
115$spring2{"foo"}->[3] = 4;
1c509eb9 116is (join(':',@{$spring2{"foo"}}), "1:2:3:4");
79072805
LW
117
118# Test references to subroutines.
119
1c509eb9
NC
120{
121 my $called;
122 sub mysub { $called++; }
123 $subref = \&mysub;
124 &$subref;
125 is ($called, 1);
126}
79072805
LW
127
128$subrefref = \\&mysub2;
1c509eb9
NC
129is ($$subrefref->("GOOD"), "good");
130sub mysub2 { lc shift }
79072805
LW
131
132# Test the ref operator.
133
1c509eb9
NC
134is (ref $subref, 'CODE');
135is (ref $ref, 'ARRAY');
136is (ref $refref, 'HASH');
79072805
LW
137
138# Test anonymous hash syntax.
139
140$anonhash = {};
1c509eb9 141is (ref $anonhash, 'HASH');
e24631be 142$anonhash2 = {FOO => 'BAR', ABC => 'XYZ',};
1c509eb9 143is (join('', sort values %$anonhash2), 'BARXYZ');
79072805
LW
144
145# Test bless operator.
146
147package MYHASH;
148
149$object = bless $main'anonhash2;
1c509eb9
NC
150main::is (ref $object, 'MYHASH');
151main::is ($object->{ABC}, 'XYZ');
79072805
LW
152
153$object2 = bless {};
1c509eb9 154main::is (ref $object2, 'MYHASH');
79072805
LW
155
156# Test ordinary call on object method.
157
1c509eb9 158&mymethod($object,"argument");
79072805
LW
159
160sub mymethod {
161 local($THIS, @ARGS) = @_;
ed6116ce 162 die 'Got a "' . ref($THIS). '" instead of a MYHASH'
e24631be 163 unless ref $THIS eq 'MYHASH';
1c509eb9
NC
164 main::is ($ARGS[0], "argument");
165 main::is ($THIS->{FOO}, 'BAR');
79072805
LW
166}
167
168# Test automatic destructor call.
169
1c509eb9 170$string = "bad";
79072805 171$object = "foo";
1c509eb9 172$string = "good";
79072805 173$main'anonhash2 = "foo";
8990e307 174$string = "";
79072805 175
ed6116ce 176DESTROY {
8990e307 177 return unless $string;
1c509eb9 178 main::is ($string, 'good');
79072805 179
a0d0e21e 180 # Test that the object has not already been "cursed".
1c509eb9 181 main::isnt (ref shift, 'HASH');
79072805
LW
182}
183
184# Now test inheritance of methods.
185
186package OBJ;
187
e24631be 188@ISA = ('BASEOBJ');
79072805 189
e24631be 190$main'object = bless {FOO => 'foo', BAR => 'bar'};
79072805
LW
191
192package main;
193
194# Test arrow-style method invocation.
195
e24631be 196is ($object->doit("BAR"), 'bar');
79072805
LW
197
198# Test indirect-object-style method invocation.
199
200$foo = doit $object "FOO";
e24631be 201main::is ($foo, 'foo');
79072805
LW
202
203sub BASEOBJ'doit {
204 local $ref = shift;
e24631be 205 die "Not an OBJ" unless ref $ref eq 'OBJ';
748a9306 206 $ref->{shift()};
79072805 207}
8990e307 208
a0d0e21e
LW
209package UNIVERSAL;
210@ISA = 'LASTCHANCE';
211
212package LASTCHANCE;
805232b4 213sub foo { main::is ($_[1], 'works') }
a0d0e21e
LW
214
215package WHATEVER;
805232b4 216foo WHATEVER "works";
a0d0e21e 217
58e0a6ae
GS
218#
219# test the \(@foo) construct
220#
221package main;
fb53bbb2 222@foo = \(1..3);
58e0a6ae
GS
223@bar = \(@foo);
224@baz = \(1,@foo,@bar);
805232b4
NC
225is (scalar (@bar), 3);
226is (scalar grep(ref($_), @bar), 3);
227is (scalar (@baz), 3);
58e0a6ae 228
fb53bbb2 229my(@fuu) = \(1..2,3);
58e0a6ae
GS
230my(@baa) = \(@fuu);
231my(@bzz) = \(1,@fuu,@baa);
805232b4
NC
232is (scalar (@baa), 3);
233is (scalar grep(ref($_), @baa), 3);
234is (scalar (@bzz), 3);
58e0a6ae 235
75ea820e
SM
236# also, it can't be an lvalue
237eval '\\($x, $y) = (1, 2);';
805232b4 238like ($@, qr/Can\'t modify.*ref.*in.*assignment/);
75ea820e 239
bc44cdaf 240# test for proper destruction of lexical objects
1c509eb9 241$test = curr_test();
805232b4
NC
242sub larry::DESTROY { print "# larry\nok $test\n"; }
243sub curly::DESTROY { print "# curly\nok ", $test + 1, "\n"; }
244sub moe::DESTROY { print "# moe\nok ", $test + 2, "\n"; }
bc44cdaf
GS
245
246{
247 my ($joe, @curly, %larry);
248 my $moe = bless \$joe, 'moe';
249 my $curly = bless \@curly, 'curly';
250 my $larry = bless \%larry, 'larry';
251 print "# leaving block\n";
252}
253
254print "# left block\n";
805232b4 255curr_test($test + 3);
bc44cdaf 256
fb73857a 257# another glob test
258
805232b4
NC
259
260$foo = "garbage";
fb73857a 261{ local(*bar) = "foo" }
805232b4 262$bar = "glob 3";
fb73857a 263local(*bar) = *bar;
805232b4 264is ($bar, "glob 3");
fb73857a 265
805232b4 266$var = "glob 4";
d4010388 267$_ = \$var;
805232b4 268is ($$_, 'glob 4');
d4010388 269
4e8e7886 270
805232b4
NC
271# test if reblessing during destruction results in more destruction
272$test = curr_test();
4e8e7886
GS
273{
274 package A;
275 sub new { bless {}, shift }
805232b4 276 DESTROY { print "# destroying 'A'\nok ", $test + 1, "\n" }
8bac7e00 277 package _B;
4e8e7886 278 sub new { bless {}, shift }
805232b4 279 DESTROY { print "# destroying '_B'\nok $test\n"; bless shift, 'A' }
4e8e7886 280 package main;
8bac7e00 281 my $b = _B->new;
4e8e7886 282}
805232b4 283curr_test($test + 2);
4e8e7886
GS
284
285# test if $_[0] is properly protected in DESTROY()
286
287{
805232b4 288 my $test = curr_test();
4e8e7886
GS
289 my $i = 0;
290 local $SIG{'__DIE__'} = sub {
291 my $m = shift;
292 if ($i++ > 4) {
805232b4 293 print "# infinite recursion, bailing\nnot ok $test\n";
4e8e7886
GS
294 exit 1;
295 }
805232b4 296 like ($m, qr/^Modification of a read-only/);
4e8e7886
GS
297 };
298 package C;
299 sub new { bless {}, shift }
300 DESTROY { $_[0] = 'foo' }
301 {
302 print "# should generate an error...\n";
303 my $c = C->new;
304 }
305 print "# good, didn't recurse\n";
306}
307
0dd88869 308# test if refgen behaves with autoviv magic
0dd88869
GS
309{
310 my @a;
805232b4
NC
311 $a[1] = "good";
312 my $got;
313 for (@a) {
314 $got .= ${\$_};
315 $got .= ';';
316 }
317 is ($got, ";good;");
0dd88869
GS
318}
319
840a7b70
IZ
320# This test is the reason for postponed destruction in sv_unref
321$a = [1,2,3];
322$a = $a->[1];
805232b4 323is ($a, 2);
840a7b70 324
04ca4930
NC
325# This test used to coredump. The BEGIN block is important as it causes the
326# op that created the constant reference to be freed. Hence the only
327# reference to the constant string "pass" is in $a. The hack that made
328# sure $a = $a->[1] would work didn't work with references to constants.
329
04ca4930
NC
330
331foreach my $lexical ('', 'my $a; ') {
332 my $expect = "pass\n";
333 my $result = runperl (switches => ['-wl'], stderr => 1,
334 prog => $lexical . 'BEGIN {$a = \q{pass}}; $a = $$a; print $a');
335
805232b4
NC
336 is ($?, 0);
337 is ($result, $expect);
840a7b70
IZ
338}
339
e24631be 340$test = curr_test();
04ca4930
NC
341sub x::DESTROY {print "ok ", $test + shift->[0], "\n"}
342{ my $a1 = bless [3],"x";
343 my $a2 = bless [2],"x";
344 { my $a3 = bless [1],"x";
345 my $a4 = bless [0],"x";
346 567;
347 }
348}
805232b4
NC
349curr_test($test+4);
350
351is (runperl (switches=>['-l'],
352 prog=> 'print 1; print qq-*$\*-;print 1;'),
353 "1\n*\n*\n1\n");
b2ce0fda 354
39cff0d9
AE
355# bug #21347
356
357runperl(prog => 'sub UNIVERSAL::AUTOLOAD { qr// } a->p' );
805232b4 358is ($?, 0, 'UNIVERSAL::AUTOLOAD called when freeing qr//');
39cff0d9 359
7b102d90 360runperl(prog => 'sub UNIVERSAL::DESTROY { warn } bless \$a, A', stderr => 1);
805232b4 361is ($?, 0, 'warn called inside UNIVERSAL::DESTROY');
7b102d90 362
23bb1b96
DM
363
364# bug #22719
365
366runperl(prog => 'sub f { my $x = shift; *z = $x; } f({}); f();');
805232b4 367is ($?, 0, 'coredump on typeglob = (SvRV && !SvROK)');
23bb1b96 368
ec5f3c78
DM
369# bug #27268: freeing self-referential typeglobs could trigger
370# "Attempt to free unreferenced scalar" warnings
371
805232b4 372is (runperl(
ec5f3c78
DM
373 prog => 'use Symbol;my $x=bless \gensym,"t"; print;*$$x=$x',
374 stderr => 1
805232b4 375), '', 'freeing self-referential typeglob');
23bb1b96 376
804ffa60
DM
377# using a regex in the destructor for STDOUT segfaulted because the
378# REGEX pad had already been freed (ithreads build only). The
379# object is required to trigger the early freeing of GV refs to to STDOUT
380
805232b4 381like (runperl(
804ffa60
DM
382 prog => '$x=bless[]; sub IO::Handle::DESTROY{$_="bad";s/bad/ok/;print}',
383 stderr => 1
805232b4 384 ), qr/^(ok)+$/, 'STDOUT destructor');
804ffa60 385
512d1826
NC
386TODO: {
387 no strict 'refs';
388 $name8 = chr 163;
389 $name_utf8 = $name8 . chr 256;
390 chop $name_utf8;
391
392 is ($$name8, undef, 'Nothing before we start');
393 is ($$name_utf8, undef, 'Nothing before we start');
394 $$name8 = "Pound";
395 is ($$name8, "Pound", 'Accessing via 8 bit symref works');
396 local $TODO = "UTF8 mangled in symrefs";
397 is ($$name_utf8, "Pound", 'Accessing via UTF8 symref works');
398}
399
400TODO: {
401 no strict 'refs';
402 $name_utf8 = $name = chr 9787;
403 utf8::encode $name_utf8;
404
405 is (length $name, 1, "Name is 1 char");
406 is (length $name_utf8, 3, "UTF8 representation is 3 chars");
407
408 is ($$name, undef, 'Nothing before we start');
409 is ($$name_utf8, undef, 'Nothing before we start');
410 $$name = "Face";
411 is ($$name, "Face", 'Accessing via Unicode symref works');
412 local $TODO = "UTF8 mangled in symrefs";
413 is ($$name_utf8, undef,
414 'Accessing via the UTF8 byte sequence gives nothing');
415}
416
417TODO: {
418 no strict 'refs';
419 $name1 = "\0Chalk";
420 $name2 = "\0Cheese";
421
422 isnt ($name1, $name2, "They differ");
423
424 is ($$name1, undef, 'Nothing before we start');
425 is ($$name2, undef, 'Nothing before we start');
b3d904f3 426 $$name1 = "Yummy";
512d1826 427 is ($$name1, "Yummy", 'Accessing via the correct name works');
512d1826
NC
428 is ($$name2, undef,
429 'Accessing via a different NUL-containing name gives nothing');
430}
431
9a9798c2
YST
432# test derefs after list slice
433
434is ( ({foo => "bar"})[0]{foo}, "bar", 'hash deref from list slice w/o ->' );
435is ( ({foo => "bar"})[0]->{foo}, "bar", 'hash deref from list slice w/ ->' );
436is ( ([qw/foo bar/])[0][1], "bar", 'array deref from list slice w/o ->' );
437is ( ([qw/foo bar/])[0]->[1], "bar", 'array deref from list slice w/ ->' );
438is ( (sub {"bar"})[0](), "bar", 'code deref from list slice w/o ->' );
439is ( (sub {"bar"})[0]->(), "bar", 'code deref from list slice w/ ->' );
440
441# deref on empty list shouldn't autovivify
442{
443 local $@;
444 eval { ()[0]{foo} };
445 like ( "$@", "Can't use an undefined value as a HASH reference",
446 "deref of undef from list slice fails" );
447}
448
cbae9b9f
YST
449# test dereferencing errors
450{
451 eval q/ ${*STDOUT{IO}} /;
452 like($@, qr/Not a SCALAR reference/);
453 eval q/ @{*STDOUT{IO}} /;
454 like($@, qr/Not an ARRAY reference/);
455 eval q/ %{*STDOUT{IO}} /;
456 like($@, qr/Not a HASH reference/);
457 eval q/ &{*STDOUT{IO}} /;
458 like($@, qr/Not a CODE reference/);
459}
460
805232b4
NC
461# Bit of a hack to make test.pl happy. There are 3 more tests after it leaves.
462$test = curr_test();
463curr_test($test + 3);
4e8e7886
GS
464# test global destruction
465
840a7b70
IZ
466my $test1 = $test + 1;
467my $test2 = $test + 2;
468
8990e307
LW
469package FINALE;
470
471{
840a7b70
IZ
472 $ref3 = bless ["ok $test2\n"]; # package destruction
473 my $ref2 = bless ["ok $test1\n"]; # lexical destruction
474 local $ref1 = bless ["ok $test\n"]; # dynamic destruction
8990e307
LW
475 1; # flush any temp values on stack
476}
477
478DESTROY {
479 print $_[0][0];
480}
804ffa60 481