This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
lvref.t: Repeat bad ref tests with list assignment
[perl5.git] / t / op / lvref.t
CommitLineData
72ed4618
FC
1BEGIN {
2 chdir 't';
3 require './test.pl';
4 set_up_inc("../lib");
5}
6
bd9bf01b 7plan 111;
72ed4618 8
53abf431
FC
9sub on { $::TODO = ' ' }
10sub off{ $::TODO = '' }
72ed4618
FC
11
12eval '\$x = \$y';
13like $@, qr/^Experimental lvalue references not enabled/,
14 'error when feature is disabled';
26a50d99
FC
15eval '\($x) = \$y';
16like $@, qr/^Experimental lvalue references not enabled/,
17 'error when feature is disabled (aassign)';
72ed4618
FC
18
19use feature 'lvalue_refs';
20
21{
22 my($w,$c);
23 local $SIG{__WARN__} = sub { $c++; $w = shift };
24 eval '\$x = \$y';
25 is $c, 1, 'one warning from lv ref assignment';
26 like $w, qr/^Lvalue references are experimental/,
27 'experimental warning';
26a50d99
FC
28 undef $c;
29 eval '\($x) = \$y';
30 is $c, 1, 'one warning from lv ref list assignment';
31 like $w, qr/^Lvalue references are experimental/,
32 'experimental warning';
72ed4618
FC
33}
34
35no warnings 'experimental::lvalue_refs';
36
37# Scalars
38
39eval '\$x = \$y';
40is \$x, \$y, '\$pkg_scalar = ...';
41my $m;
53abf431 42\$m = \$y;
72ed4618 43is \$m, \$y, '\$lexical = ...';
fc048fcf 44\my $n = \$y;
72ed4618
FC
45is \$n, \$y, '\my $lexical = ...';
46@_ = \$_;
26a50d99 47\($x) = @_;
72ed4618 48is \$x, \$_, '\($pkgvar) = ... gives list context';
238ef7dc 49undef *x;
26a50d99 50(\$x) = @_;
238ef7dc 51is \$x, \$_, '(\$pkgvar) = ... gives list context';
72ed4618 52my $o;
c146a62a 53\($o) = @_;
72ed4618 54is \$o, \$_, '\($lexical) = ... gives list cx';
26a50d99 55my $q;
c146a62a 56(\$q) = @_;
238ef7dc 57is \$q, \$_, '(\$lexical) = ... gives list cx';
c146a62a 58\(my $p) = @_;
72ed4618 59is \$p, \$_, '\(my $lexical) = ... gives list cx';
c146a62a 60(\my $r) = @_;
238ef7dc 61is \$r, \$_, '(\my $lexical) = ... gives list cx';
c146a62a 62\my($s) = @_;
238ef7dc 63is \$s, \$_, '\my($lexical) = ... gives list cx';
217e3565 64\($_a, my $a) = @{[\$b, \$c]};
72ed4618
FC
65is \$_a, \$b, 'package scalar in \(...)';
66is \$a, \$c, 'lex scalar in \(...)';
c146a62a 67(\$_b, \my $b) = @{[\$b, \$c]};
72ed4618
FC
68is \$_b, \$::b, 'package scalar in (\$foo, \$bar)';
69is \$b, \$c, 'lex scalar in (\$foo, \$bar)';
2a57afb1
FC
70is do { \local $l = \3; $l }, 3, '\local $scalar assignment';
71is $l, undef, 'localisation unwound';
72is do { \(local $l) = \4; $l }, 4, '\(local $scalar) assignment';
11ea28ee 73is $l, undef, 'localisation unwound';
29a3d628
FC
74\$foo = \*bar;
75is *foo{SCALAR}, *bar{GLOB}, 'globref-to-scalarref assignment';
72ed4618
FC
76
77# Array Elements
78
0ca7b7f7
FC
79sub expect_scalar_cx { wantarray ? 0 : \$_ }
80sub expect_list_cx { wantarray ? (\$_,\$_) : 0 }
81\$a[0] = expect_scalar_cx;
6102323a 82is \$a[0], \$_, '\$array[0]';
0ca7b7f7 83\($a[1]) = expect_list_cx;
6102323a
FC
84is \$a[1], \$_, '\($array[0])';
85{
86 my @a;
0ca7b7f7 87 \$a[0] = expect_scalar_cx;
6102323a 88 is \$a[0], \$_, '\$lexical_array[0]';
0ca7b7f7 89 \($a[1]) = expect_list_cx;
6102323a 90 is \$a[1], \$_, '\($lexical_array[0])';
40d2b828
FC
91 my $tmp;
92 {
93 \local $a[0] = \$tmp;
94 is \$a[0], \$tmp, '\local $a[0]';
95 }
96 is \$a[0], \$_, '\local $a[0] unwound';
97 {
98 \local ($a[1]) = \$tmp;
99 is \$a[1], \$tmp, '\local ($a[0])';
100 }
101 is \$a[1], \$_, '\local $a[0] unwound';
6102323a 102}
0ca7b7f7
FC
103{
104 my @a;
105 \@a[0,1] = expect_list_cx;
106 is \$a[0].\$a[1], \$_.\$_, '\@array[indices]';
107 \(@a[2,3]) = expect_list_cx;
108 is \$a[0].\$a[1], \$_.\$_, '\(@array[indices])';
109 my $tmp;
110 {
111 \local @a[0,1] = (\$tmp)x2;
112 is \$a[0].\$a[1], \$tmp.\$tmp, '\local @a[indices]';
113 }
114 is \$a[0].\$a[1], \$_.\$_, '\local @a[indices] unwound';
115}
72ed4618
FC
116
117# Hash Elements
118
5f94141d
FC
119\$h{a} = expect_scalar_cx;
120is \$h{a}, \$_, '\$hash{a}';
121\($h{b}) = expect_list_cx;
122is \$h{b}, \$_, '\($hash{a})';
123{
124 my @h;
125 \$h{a} = expect_scalar_cx;
126 is \$h{a}, \$_, '\$lexical_array{a}';
127 \($h{b}) = expect_list_cx;
128 is \$h{b}, \$_, '\($lexical_array{a})';
129 my $tmp;
130 {
131 \local $h{a} = \$tmp;
132 is \$h{a}, \$tmp, '\local $h{a}';
133 }
134 is \$h{a}, \$_, '\local $h{a} unwound';
135 {
136 \local ($h{b}) = \$tmp;
137 is \$h{b}, \$tmp, '\local ($h{a})';
138 }
139 is \$h{b}, \$_, '\local $h{a} unwound';
140}
141{
142 my @h;
143 \@h{"a","b"} = expect_list_cx;
144 is \$h{a}.\$h{b}, \$_.\$_, '\@hash{indices}';
145 \(@h{2,3}) = expect_list_cx;
146 is \$h{a}.\$h{b}, \$_.\$_, '\(@hash{indices})';
147 my $tmp;
148 {
149 \local @h{"a","b"} = (\$tmp)x2;
150 is \$h{a}.\$h{b}, \$tmp.\$tmp, '\local @h{indices}';
151 }
152 is \$h{a}.\$h{b}, \$_.\$_, '\local @h{indices} unwound';
153}
72ed4618
FC
154
155# Arrays
156
4779e7f9
FC
157package ArrayTest {
158 BEGIN { *is = *main::is }
159 sub expect_scalar_cx { wantarray ? 0 : \@ThatArray }
160 sub expect_list_cx { wantarray ? (\$_,\$_) : 0 }
161 sub expect_list_cx_a { wantarray ? (\@ThatArray)x2 : 0 }
162 eval '\@a = expect_scalar_cx';
163 is \@a, \@ThatArray, '\@pkg';
164 my @a;
3f114923 165 \@a = expect_scalar_cx;
4779e7f9 166 is \@a, \@ThatArray, '\@lexical';
9782ce69 167 (\@b) = expect_list_cx_a;
4779e7f9
FC
168 is \@b, \@ThatArray, '(\@pkg)';
169 my @b;
9782ce69 170 (\@b) = expect_list_cx_a;
4779e7f9 171 is \@b, \@ThatArray, '(\@lexical)';
3f114923 172 \my @c = expect_scalar_cx;
4779e7f9 173 is \@c, \@ThatArray, '\my @lexical';
bdaf10a5 174 (\my @d) = expect_list_cx_a;
4779e7f9 175 is \@d, \@ThatArray, '(\my @lexical)';
bdaf10a5
FC
176 \(@e) = expect_list_cx;
177 is \$e[0].\$e[1], \$_.\$_, '\(@pkg)';
4779e7f9 178 my @e;
bdaf10a5
FC
179 \(@e) = expect_list_cx;
180 is \$e[0].\$e[1], \$_.\$_, '\(@lexical)';
181 \(my @f) = expect_list_cx;
182 is \$f[0].\$f[1], \$_.\$_, '\(my @lexical)';
183 \my(@g) = expect_list_cx;
184 is \$g[0].\$g[1], \$_.\$_, '\my(@lexical)';
30494daf 185 my $old = \@h;
30494daf
FC
186 {
187 \local @h = \@ThatArray;
188 is \@h, \@ThatArray, '\local @a';
189 }
30494daf
FC
190 is \@h, $old, '\local @a unwound';
191 $old = \@i;
30494daf
FC
192 eval q{
193 (\local @i) = \@ThatArray;
194 is \@i, \@ThatArray, '(\local @a)';
195 } or do { SKIP: { ::skip 'unimplemented' } };
196 is \@i, $old, '(\local @a) unwound';
4779e7f9 197}
72ed4618
FC
198
199# Hashes
200
87da42eb
FC
201package HashTest {
202 BEGIN { *is = *main::is }
203 sub expect_scalar_cx { wantarray ? 0 : \%ThatHash }
204 sub expect_list_cx { wantarray ? (\%ThatHash)x2 : 0 }
3f114923 205 \%a = expect_scalar_cx;
87da42eb
FC
206 is \%a, \%ThatHash, '\%pkg';
207 my %a;
3f114923 208 \%a = expect_scalar_cx;
87da42eb 209 is \%a, \%ThatHash, '\%lexical';
9782ce69
FC
210 (\%b) = expect_list_cx;
211 is \%b, \%ThatHash, '(\%pkg)';
87da42eb 212 my %b;
9782ce69 213 (\%b) = expect_list_cx;
87da42eb 214 is \%b, \%ThatHash, '(\%lexical)';
3f114923 215 \my %c = expect_scalar_cx;
87da42eb 216 is \%c, \%ThatHash, '\my %lexical';
9782ce69 217 (\my %d) = expect_list_cx;
87da42eb 218 is \%d, \%ThatHash, '(\my %lexical)';
30494daf 219 my $old = \%h;
30494daf
FC
220 {
221 \local %h = \%ThatHash;
222 is \%h, \%ThatHash, '\local %a';
223 }
30494daf
FC
224 is \%h, $old, '\local %a unwound';
225 $old = \%i;
30494daf
FC
226 eval q{
227 (\local %i) = \%ThatHash;
228 is \%i, \%ThatHash, '(\local %a)';
229 } or do { SKIP: { ::skip 'unimplemented' } };
230 is \%i, $old, '(\local %a) unwound';
87da42eb 231}
72ed4618
FC
232
233# Subroutines
234
235# ...
236
b7ae253e 237# Mixed List Assignments
72ed4618 238
26a50d99 239(\$tahi, $rua) = \(1,2);
9fc71ff4
FC
240is join(' ', $tahi, $$rua), '1 2',
241 'mixed scalar ref and scalar list assignment';
b7ae253e
FC
242
243# Conditional expressions
244
9fc71ff4 245$_ = 3;
d1094c5b 246$_ == 3 ? \$tahi : $rua = \3;
9fc71ff4 247is $tahi, 3, 'cond assignment resolving to scalar ref';
d1094c5b 248$_ == 0 ? \$toru : $wha = \3;
9fc71ff4 249is $$wha, 3, 'cond assignment resolving to scalar';
d1094c5b 250$_ == 3 ? \$rima : \$ono = \5;
9e592f5a 251is $rima, 5, 'cond assignment with refgens on both branches';
7664512e
FC
252\($_ == 3 ? $whitu : $waru) = \5;
253is $whitu, 5, '\( ?: ) assignment';
72ed4618 254
096cc2cc
FC
255# Foreach
256
9e592f5a 257on;
096cc2cc
FC
258eval '
259 for \my $a(\$for1, \$for2) {
260 push @for, \$a;
261 }
262';
263is "@for", \$for1 . ' ' . \$for2, 'foreach \my $a';
264
265@for = ();
266eval '
267 for \my @a([1,2], [3,4]) {
268 push @for, @a;
269 }
270';
271is "@for", "1 2 3 4", 'foreach \my @a [perl #22335]';
272
273@for = ();
274eval '
275 for \my %a({5,6}, {7,8}) {
276 push @for, %a;
277 }
278';
279is "@for", "5 6 7 8", 'foreach \my %a [perl #22335]';
280
281@for = ();
282eval '
283 for \my &a(sub {9}, sub {10}) {
284 push @for, &a;
285 }
286';
287is "@for", "9 10", 'foreach \my &a';
288
289
72ed4618
FC
290# Errors
291
b3717a0e
FC
292off;
293eval { my $x; \$x = 3 };
294like $@, qr/^Assigned value is not a reference at/, 'assigning non-ref';
295eval { my $x; \$x = [] };
296like $@, qr/^Assigned value is not a SCALAR reference at/,
297 'assigning non-scalar ref to scalar ref';
d8a875d9
FC
298eval { \$::x = [] };
299like $@, qr/^Assigned value is not a SCALAR reference at/,
300 'assigning non-scalar ref to package scalar ref';
0719038d
FC
301eval { my @x; \@x = {} };
302like $@, qr/^Assigned value is not an ARRAY reference at/,
303 'assigning non-array ref to array ref';
304eval { \@::x = {} };
305like $@, qr/^Assigned value is not an ARRAY reference at/,
306 'assigning non-array ref to package array ref';
307eval { my %x; \%x = [] };
308like $@, qr/^Assigned value is not a HASH reference at/,
309 'assigning non-hash ref to hash ref';
310eval { \%::x = [] };
311like $@, qr/^Assigned value is not a HASH reference at/,
312 'assigning non-hash ref to package hash ref';
d6378458 313
bd9bf01b
FC
314eval { my $x; (\$x) = 3 };
315like $@, qr/^Assigned value is not a reference at/,
316 'list-assigning non-ref';
317eval { my $x; (\$x) = [] };
318like $@, qr/^Assigned value is not a SCALAR reference at/,
319 'list-assigning non-scalar ref to scalar ref';
320eval { (\$::x = []) };
321like $@, qr/^Assigned value is not a SCALAR reference at/,
322 'list-assigning non-scalar ref to package scalar ref';
323eval { my @x; (\@x) = {} };
324like $@, qr/^Assigned value is not an ARRAY reference at/,
325 'list-assigning non-array ref to array ref';
326eval { (\@::x) = {} };
327like $@, qr/^Assigned value is not an ARRAY reference at/,
328 'list-assigning non-array ref to package array ref';
329eval { my %x; (\%x) = [] };
330like $@, qr/^Assigned value is not a HASH reference at/,
331 'list-assigning non-hash ref to hash ref';
332eval { (\%::x) = [] };
333like $@, qr/^Assigned value is not a HASH reference at/,
334 'list-assigning non-hash ref to package hash ref';
335
d6378458
FC
336eval '(\do{}) = 42';
337like $@, qr/^Can't modify reference to do block in list assignment at /,
338 "Can't modify reference to do block in list assignment";
d6378458
FC
339eval '(\pos) = 42';
340like $@,
341 qr/^Can't modify reference to match position in list assignment at /,
342 "Can't modify ref to some scalar-returning op in list assignment";
d6378458
FC
343eval '(\glob) = 42';
344like $@,
345 qr/^Can't modify reference to glob in list assignment at /,
346 "Can't modify reference to some list-returning op in list assignment";
d6b7592f
FC
347eval '\pos = 42';
348like $@,
349 qr/^Can't modify reference to match position in scalar assignment at /,
350 "Can't modify ref to some scalar-returning op in scalar assignment";
30494daf
FC
351eval '\(local @b) = 42';
352like $@,
bdaf10a5 353 qr/^Can't modify reference to localized parenthesized array in list(?x:
30494daf
FC
354 ) assignment at /,
355 q"Can't modify \(local @array) in list assignment";
356eval '\local(@b) = 42';
357like $@,
bdaf10a5 358 qr/^Can't modify reference to localized parenthesized array in list(?x:
30494daf
FC
359 ) assignment at /,
360 q"Can't modify \local(@array) in list assignment";
bdaf10a5
FC
361eval '\local(@{foo()}) = 42';
362like $@,
363 qr/^Can't modify reference to array dereference in list assignment at/,
364 q"'Array deref' error takes prec. over 'local paren' error";
87da42eb
FC
365eval '\(%b) = 42';
366like $@,
367 qr/^Can't modify reference to parenthesized hash in list assignment a/,
368 "Can't modify ref to parenthesized package hash in scalar assignment";
369eval '\(my %b) = 42';
370like $@,
371 qr/^Can't modify reference to parenthesized hash in list assignment a/,
372 "Can't modify ref to parenthesized hash (\(my %b)) in list assignment";
373eval '\my(%b) = 42';
374like $@,
375 qr/^Can't modify reference to parenthesized hash in list assignment a/,
376 "Can't modify ref to parenthesized hash (\my(%b)) in list assignment";
377eval '\%{"42"} = 42';
378like $@,
379 qr/^Can't modify reference to hash dereference in scalar assignment a/,
380 "Can't modify reference to hash dereference in scalar assignment";
3f114923 381on;
87da42eb 382
781ff25d
FC
383
384# Miscellaneous
385
386{
387 my($x,$y);
388 sub {
389 sub {
390 \$x = \$y;
391 }->();
392 is \$x, \$y, 'lexical alias affects outer closure';
393 }->();
394 is \$x, \$y, 'lexical alias affects outer sub where vars are declared';
395}
81cb1af6
FC
396
397{ # PADSTALE has a double meaning
398 use feature 'lexical_subs', 'signatures', 'state';
399 no warnings 'experimental';
400 my $c;
401 my sub s ($arg) {
402 state $x = ++$c;
403 if ($arg == 3) { return $c }
404 goto skip if $arg == 2;
405 my $y;
406 skip:
407 # $y is PADSTALE the 2nd time
408 \$x = \$y if $arg == 2;
409 }
410 s(1);
411 s(2);
412 is s(3), 1, 'padstale alias should not reset state'
413}
cf5d2d91
FC
414
415off;
416SKIP: {
417 skip_without_dynamic_extension('List/Util');
418 require Scalar::Util;
419 my $a;
420 Scalar::Util::weaken($r = \$a);
421 \$a = $r;
422 pass 'no crash when assigning \$lex = $weakref_to_lex'
423}