Commit | Line | Data |
---|---|---|
72ed4618 FC |
1 | BEGIN { |
2 | chdir 't'; | |
3 | require './test.pl'; | |
4 | set_up_inc("../lib"); | |
5 | } | |
6 | ||
0ca7b7f7 | 7 | plan 52; |
72ed4618 | 8 | |
53abf431 FC |
9 | sub on { $::TODO = ' ' } |
10 | sub off{ $::TODO = '' } | |
72ed4618 FC |
11 | |
12 | eval '\$x = \$y'; | |
13 | like $@, qr/^Experimental lvalue references not enabled/, | |
14 | 'error when feature is disabled'; | |
26a50d99 FC |
15 | eval '\($x) = \$y'; |
16 | like $@, qr/^Experimental lvalue references not enabled/, | |
17 | 'error when feature is disabled (aassign)'; | |
72ed4618 FC |
18 | |
19 | use 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 | ||
35 | no warnings 'experimental::lvalue_refs'; | |
36 | ||
37 | # Scalars | |
38 | ||
39 | eval '\$x = \$y'; | |
40 | is \$x, \$y, '\$pkg_scalar = ...'; | |
41 | my $m; | |
53abf431 | 42 | \$m = \$y; |
72ed4618 | 43 | is \$m, \$y, '\$lexical = ...'; |
fc048fcf | 44 | \my $n = \$y; |
72ed4618 FC |
45 | is \$n, \$y, '\my $lexical = ...'; |
46 | @_ = \$_; | |
26a50d99 | 47 | \($x) = @_; |
72ed4618 | 48 | is \$x, \$_, '\($pkgvar) = ... gives list context'; |
238ef7dc | 49 | undef *x; |
26a50d99 | 50 | (\$x) = @_; |
238ef7dc | 51 | is \$x, \$_, '(\$pkgvar) = ... gives list context'; |
72ed4618 | 52 | my $o; |
c146a62a | 53 | \($o) = @_; |
72ed4618 | 54 | is \$o, \$_, '\($lexical) = ... gives list cx'; |
26a50d99 | 55 | my $q; |
c146a62a | 56 | (\$q) = @_; |
238ef7dc | 57 | is \$q, \$_, '(\$lexical) = ... gives list cx'; |
c146a62a | 58 | \(my $p) = @_; |
72ed4618 | 59 | is \$p, \$_, '\(my $lexical) = ... gives list cx'; |
c146a62a | 60 | (\my $r) = @_; |
238ef7dc | 61 | is \$r, \$_, '(\my $lexical) = ... gives list cx'; |
c146a62a | 62 | \my($s) = @_; |
238ef7dc | 63 | is \$s, \$_, '\my($lexical) = ... gives list cx'; |
217e3565 | 64 | \($_a, my $a) = @{[\$b, \$c]}; |
72ed4618 FC |
65 | is \$_a, \$b, 'package scalar in \(...)'; |
66 | is \$a, \$c, 'lex scalar in \(...)'; | |
c146a62a | 67 | (\$_b, \my $b) = @{[\$b, \$c]}; |
72ed4618 FC |
68 | is \$_b, \$::b, 'package scalar in (\$foo, \$bar)'; |
69 | is \$b, \$c, 'lex scalar in (\$foo, \$bar)'; | |
2a57afb1 FC |
70 | is do { \local $l = \3; $l }, 3, '\local $scalar assignment'; |
71 | is $l, undef, 'localisation unwound'; | |
72 | is do { \(local $l) = \4; $l }, 4, '\(local $scalar) assignment'; | |
11ea28ee | 73 | is $l, undef, 'localisation unwound'; |
29a3d628 FC |
74 | \$foo = \*bar; |
75 | is *foo{SCALAR}, *bar{GLOB}, 'globref-to-scalarref assignment'; | |
72ed4618 FC |
76 | |
77 | # Array Elements | |
78 | ||
0ca7b7f7 FC |
79 | sub expect_scalar_cx { wantarray ? 0 : \$_ } |
80 | sub expect_list_cx { wantarray ? (\$_,\$_) : 0 } | |
81 | \$a[0] = expect_scalar_cx; | |
6102323a | 82 | is \$a[0], \$_, '\$array[0]'; |
0ca7b7f7 | 83 | \($a[1]) = expect_list_cx; |
6102323a FC |
84 | is \$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 FC |
90 | is \$a[1], \$_, '\($lexical_array[0])'; |
91 | } | |
0ca7b7f7 FC |
92 | { |
93 | my @a; | |
94 | \@a[0,1] = expect_list_cx; | |
95 | is \$a[0].\$a[1], \$_.\$_, '\@array[indices]'; | |
96 | \(@a[2,3]) = expect_list_cx; | |
97 | is \$a[0].\$a[1], \$_.\$_, '\(@array[indices])'; | |
98 | my $tmp; | |
99 | { | |
100 | \local @a[0,1] = (\$tmp)x2; | |
101 | is \$a[0].\$a[1], \$tmp.\$tmp, '\local @a[indices]'; | |
102 | } | |
103 | is \$a[0].\$a[1], \$_.\$_, '\local @a[indices] unwound'; | |
104 | } | |
72ed4618 FC |
105 | |
106 | # Hash Elements | |
107 | ||
108 | # ... | |
109 | ||
110 | # Arrays | |
111 | ||
112 | # ... | |
113 | ||
114 | # Hashes | |
115 | ||
116 | # ... | |
117 | ||
118 | # Subroutines | |
119 | ||
120 | # ... | |
121 | ||
b7ae253e | 122 | # Mixed List Assignments |
72ed4618 | 123 | |
26a50d99 | 124 | (\$tahi, $rua) = \(1,2); |
9fc71ff4 FC |
125 | is join(' ', $tahi, $$rua), '1 2', |
126 | 'mixed scalar ref and scalar list assignment'; | |
26a50d99 | 127 | on; |
b7ae253e FC |
128 | |
129 | # Conditional expressions | |
130 | ||
9fc71ff4 FC |
131 | $_ = 3; |
132 | eval '$_ == 3 ? \$tahi : $rua = \3'; | |
133 | is $tahi, 3, 'cond assignment resolving to scalar ref'; | |
134 | eval '$_ == 3 ? \$toru : $wha = \3'; | |
135 | is $$wha, 3, 'cond assignment resolving to scalar'; | |
b7ae253e FC |
136 | eval '$_ == 3 ? \$rima : \$ono = \5'; |
137 | is $$rima, 5, 'cond assignment with refgens on both branches'; | |
72ed4618 | 138 | |
096cc2cc FC |
139 | # Foreach |
140 | ||
141 | eval ' | |
142 | for \my $a(\$for1, \$for2) { | |
143 | push @for, \$a; | |
144 | } | |
145 | '; | |
146 | is "@for", \$for1 . ' ' . \$for2, 'foreach \my $a'; | |
147 | ||
148 | @for = (); | |
149 | eval ' | |
150 | for \my @a([1,2], [3,4]) { | |
151 | push @for, @a; | |
152 | } | |
153 | '; | |
154 | is "@for", "1 2 3 4", 'foreach \my @a [perl #22335]'; | |
155 | ||
156 | @for = (); | |
157 | eval ' | |
158 | for \my %a({5,6}, {7,8}) { | |
159 | push @for, %a; | |
160 | } | |
161 | '; | |
162 | is "@for", "5 6 7 8", 'foreach \my %a [perl #22335]'; | |
163 | ||
164 | @for = (); | |
165 | eval ' | |
166 | for \my &a(sub {9}, sub {10}) { | |
167 | push @for, &a; | |
168 | } | |
169 | '; | |
170 | is "@for", "9 10", 'foreach \my &a'; | |
171 | ||
172 | ||
72ed4618 FC |
173 | # Errors |
174 | ||
b3717a0e FC |
175 | off; |
176 | eval { my $x; \$x = 3 }; | |
177 | like $@, qr/^Assigned value is not a reference at/, 'assigning non-ref'; | |
178 | eval { my $x; \$x = [] }; | |
179 | like $@, qr/^Assigned value is not a SCALAR reference at/, | |
180 | 'assigning non-scalar ref to scalar ref'; | |
d8a875d9 FC |
181 | eval { \$::x = [] }; |
182 | like $@, qr/^Assigned value is not a SCALAR reference at/, | |
183 | 'assigning non-scalar ref to package scalar ref'; | |
d6378458 FC |
184 | |
185 | on; | |
186 | eval '(\do{}) = 42'; | |
187 | like $@, qr/^Can't modify reference to do block in list assignment at /, | |
188 | "Can't modify reference to do block in list assignment"; | |
189 | off; | |
190 | eval '(\pos) = 42'; | |
191 | like $@, | |
192 | qr/^Can't modify reference to match position in list assignment at /, | |
193 | "Can't modify ref to some scalar-returning op in list assignment"; | |
d6378458 FC |
194 | eval '(\glob) = 42'; |
195 | like $@, | |
196 | qr/^Can't modify reference to glob in list assignment at /, | |
197 | "Can't modify reference to some list-returning op in list assignment"; | |
d6b7592f FC |
198 | eval '\pos = 42'; |
199 | like $@, | |
200 | qr/^Can't modify reference to match position in scalar assignment at /, | |
201 | "Can't modify ref to some scalar-returning op in scalar assignment"; | |
202 | on; | |
781ff25d FC |
203 | |
204 | # Miscellaneous | |
205 | ||
206 | { | |
207 | my($x,$y); | |
208 | sub { | |
209 | sub { | |
210 | \$x = \$y; | |
211 | }->(); | |
212 | is \$x, \$y, 'lexical alias affects outer closure'; | |
213 | }->(); | |
214 | is \$x, \$y, 'lexical alias affects outer sub where vars are declared'; | |
215 | } | |
81cb1af6 FC |
216 | |
217 | { # PADSTALE has a double meaning | |
218 | use feature 'lexical_subs', 'signatures', 'state'; | |
219 | no warnings 'experimental'; | |
220 | my $c; | |
221 | my sub s ($arg) { | |
222 | state $x = ++$c; | |
223 | if ($arg == 3) { return $c } | |
224 | goto skip if $arg == 2; | |
225 | my $y; | |
226 | skip: | |
227 | # $y is PADSTALE the 2nd time | |
228 | \$x = \$y if $arg == 2; | |
229 | } | |
230 | s(1); | |
231 | s(2); | |
232 | is s(3), 1, 'padstale alias should not reset state' | |
233 | } | |
cf5d2d91 FC |
234 | |
235 | off; | |
236 | SKIP: { | |
237 | skip_without_dynamic_extension('List/Util'); | |
238 | require Scalar::Util; | |
239 | my $a; | |
240 | Scalar::Util::weaken($r = \$a); | |
241 | \$a = $r; | |
242 | pass 'no crash when assigning \$lex = $weakref_to_lex' | |
243 | } |