xref: /openbsd/gnu/usr.bin/perl/t/op/lvref.t (revision 76d0caae)
1#!perl
2BEGIN {
3    chdir 't';
4    require './test.pl';
5    set_up_inc("../lib");
6}
7
8plan 167;
9
10eval '\$x = \$y';
11like $@, qr/^Experimental aliasing via reference not enabled/,
12    'error when feature is disabled';
13eval '\($x) = \$y';
14like $@, qr/^Experimental aliasing via reference not enabled/,
15    'error when feature is disabled (aassign)';
16
17use feature 'refaliasing', 'state';
18
19{
20    my($w,$c);
21    local $SIG{__WARN__} = sub { $c++; $w = shift };
22    eval '\$x = \$y';
23    is $c, 1, 'one warning from lv ref assignment';
24    like $w, qr/^Aliasing via reference is experimental/,
25        'experimental warning';
26    undef $c;
27    eval '\($x) = \$y';
28    is $c, 1, 'one warning from lv ref list assignment';
29    like $w, qr/^Aliasing via reference is experimental/,
30        'experimental warning';
31}
32
33no warnings 'experimental::refaliasing';
34
35# Scalars
36
37\$x = \$y;
38is \$x, \$y, '\$pkg_scalar = ...';
39my $m;
40\$m = \$y;
41is \$m, \$y, '\$lexical = ...';
42\my $n = \$y;
43is \$n, \$y, '\my $lexical = ...';
44@_ = \$_;
45\($x) = @_;
46is \$x, \$_, '\($pkgvar) = ... gives list context';
47undef *x;
48(\$x) = @_;
49is \$x, \$_, '(\$pkgvar) = ... gives list context';
50my $o;
51\($o) = @_;
52is \$o, \$_, '\($lexical) = ... gives list cx';
53my $q;
54(\$q) = @_;
55is \$q, \$_, '(\$lexical) = ... gives list cx';
56\(my $p) = @_;
57is \$p, \$_, '\(my $lexical) = ... gives list cx';
58(\my $r) = @_;
59is \$r, \$_, '(\my $lexical) = ... gives list cx';
60\my($s) = @_;
61is \$s, \$_, '\my($lexical) = ... gives list cx';
62\($_a, my $a) = @{[\$b, \$c]};
63is \$_a, \$b, 'package scalar in \(...)';
64is \$a, \$c, 'lex scalar in \(...)';
65(\$_b, \my $b) = @{[\$b, \$c]};
66is \$_b, \$::b, 'package scalar in (\$foo, \$bar)';
67is \$b, \$c, 'lex scalar in (\$foo, \$bar)';
68is do { \local $l = \3; $l }, 3, '\local $scalar assignment';
69is $l, undef, 'localisation unwound';
70is do { \(local $l) = \4; $l }, 4, '\(local $scalar) assignment';
71is $l, undef, 'localisation unwound';
72\$foo = \*bar;
73is *foo{SCALAR}, *bar{GLOB}, 'globref-to-scalarref assignment';
74for (1,2) {
75  \my $x = \3,
76  \my($y) = \3,
77  \state $a = \3,
78  \state($b) = \3 if $_ == 1;
79  if ($_ == 2) {
80    is $x, undef, '\my $x = ... clears $x on scope exit';
81    is $y, undef, '\my($x) = ... clears $x on scope exit';
82    is $a, 3, '\state $x = ... does not clear $x on scope exit';
83    is $b, 3, '\state($x) = ... does not clear $x on scope exit';
84  }
85}
86
87# Array Elements
88
89sub expect_scalar_cx { wantarray ? 0 : \$_ }
90sub expect_list_cx { wantarray ? (\$_,\$_) : 0 }
91\$a[0] = expect_scalar_cx;
92is \$a[0], \$_, '\$array[0]';
93\($a[1]) = expect_list_cx;
94is \$a[1], \$_, '\($array[0])';
95{
96  my @a;
97  \$a[0] = expect_scalar_cx;
98  is \$a[0], \$_, '\$lexical_array[0]';
99  \($a[1]) = expect_list_cx;
100  is \$a[1], \$_, '\($lexical_array[0])';
101  my $tmp;
102  {
103    \local $a[0] = \$tmp;
104    is \$a[0], \$tmp, '\local $a[0]';
105  }
106  is \$a[0], \$_, '\local $a[0] unwound';
107  {
108    \local ($a[1]) = \$tmp;
109    is \$a[1], \$tmp, '\local ($a[0])';
110  }
111  is \$a[1], \$_, '\local $a[0] unwound';
112}
113{
114  my @a;
115  \@a[0,1] = expect_list_cx;
116  is \$a[0].\$a[1], \$_.\$_, '\@array[indices]';
117  \(@a[2,3]) = expect_list_cx;
118  is \$a[0].\$a[1], \$_.\$_, '\(@array[indices])';
119  my $tmp;
120  {
121    \local @a[0,1] = (\$tmp)x2;
122    is \$a[0].\$a[1], \$tmp.\$tmp, '\local @a[indices]';
123  }
124  is \$a[0].\$a[1], \$_.\$_, '\local @a[indices] unwound';
125}
126
127# Hash Elements
128
129\$h{a} = expect_scalar_cx;
130is \$h{a}, \$_, '\$hash{a}';
131\($h{b}) = expect_list_cx;
132is \$h{b}, \$_, '\($hash{a})';
133{
134  my %h;
135  \$h{a} = expect_scalar_cx;
136  is \$h{a}, \$_, '\$lexical_array{a}';
137  \($h{b}) = expect_list_cx;
138  is \$h{b}, \$_, '\($lexical_array{a})';
139  my $tmp;
140  {
141    \local $h{a} = \$tmp;
142    is \$h{a}, \$tmp, '\local $h{a}';
143  }
144  is \$h{a}, \$_, '\local $h{a} unwound';
145  {
146    \local ($h{b}) = \$tmp;
147    is \$h{b}, \$tmp, '\local ($h{a})';
148  }
149  is \$h{b}, \$_, '\local $h{a} unwound';
150}
151{
152  my %h;
153  \@h{"a","b"} = expect_list_cx;
154  is \$h{a}.\$h{b}, \$_.\$_, '\@hash{indices}';
155  \(@h{2,3}) = expect_list_cx;
156  is \$h{a}.\$h{b}, \$_.\$_, '\(@hash{indices})';
157  my $tmp;
158  {
159    \local @h{"a","b"} = (\$tmp)x2;
160    is \$h{a}.\$h{b}, \$tmp.\$tmp, '\local @h{indices}';
161  }
162  is \$h{a}.\$h{b}, \$_.\$_, '\local @h{indices} unwound';
163}
164
165# Arrays
166
167package ArrayTest {
168  BEGIN { *is = *main::is }
169  sub expect_scalar_cx { wantarray ? 0 : \@ThatArray }
170  sub expect_list_cx   { wantarray ? (\$_,\$_) : 0 }
171  sub expect_list_cx_a { wantarray ? (\@ThatArray)x2 : 0 }
172  \@a = expect_scalar_cx;
173  is \@a, \@ThatArray, '\@pkg';
174  my @a;
175  \@a = expect_scalar_cx;
176  is \@a, \@ThatArray, '\@lexical';
177  (\@b) = expect_list_cx_a;
178  is \@b, \@ThatArray, '(\@pkg)';
179  my @b;
180  (\@b) = expect_list_cx_a;
181  is \@b, \@ThatArray, '(\@lexical)';
182  \my @c = expect_scalar_cx;
183  is \@c, \@ThatArray, '\my @lexical';
184  (\my @d) = expect_list_cx_a;
185  is \@d, \@ThatArray, '(\my @lexical)';
186  \(@e) = expect_list_cx;
187  is \$e[0].\$e[1], \$_.\$_, '\(@pkg)';
188  my @e;
189  \(@e) = expect_list_cx;
190  is \$e[0].\$e[1], \$_.\$_, '\(@lexical)';
191  \(my @f) = expect_list_cx;
192  is \$f[0].\$f[1], \$_.\$_, '\(my @lexical)';
193  \my(@g) = expect_list_cx;
194  is \$g[0].\$g[1], \$_.\$_, '\my(@lexical)';
195  my $old = \@h;
196  {
197    \local @h = \@ThatArray;
198    is \@h, \@ThatArray, '\local @a';
199  }
200  is \@h, $old, '\local @a unwound';
201  $old = \@i;
202  {
203    (\local @i) = \@ThatArray;
204    is \@i, \@ThatArray, '(\local @a)';
205  }
206  is \@i, $old, '(\local @a) unwound';
207}
208for (1,2) {
209  \my @x = [1..3],
210  \my(@y) = \3,
211  \state @a = [1..3],
212  \state(@b) = \3 if $_ == 1;
213  if ($_ == 2) {
214    is @x, 0, '\my @x = ... clears @x on scope exit';
215    is @y, 0, '\my(@x) = ... clears @x on scope exit';
216    is "@a", "1 2 3", '\state @x = ... does not clear @x on scope exit';
217    is "@b", 3, '\state(@x) = ... does not clear @x on scope exit';
218  }
219}
220
221# Hashes
222
223package HashTest {
224  BEGIN { *is = *main::is }
225  sub expect_scalar_cx { wantarray ? 0 : \%ThatHash }
226  sub expect_list_cx   { wantarray ? (\%ThatHash)x2 : 0 }
227  \%a = expect_scalar_cx;
228  is \%a, \%ThatHash, '\%pkg';
229  my %a;
230  \%a = expect_scalar_cx;
231  is \%a, \%ThatHash, '\%lexical';
232  (\%b) = expect_list_cx;
233  is \%b, \%ThatHash, '(\%pkg)';
234  my %b;
235  (\%b) = expect_list_cx;
236  is \%b, \%ThatHash, '(\%lexical)';
237  \my %c = expect_scalar_cx;
238  is \%c, \%ThatHash, '\my %lexical';
239  (\my %d) = expect_list_cx;
240  is \%d, \%ThatHash, '(\my %lexical)';
241  my $old = \%h;
242  {
243    \local %h = \%ThatHash;
244    is \%h, \%ThatHash, '\local %a';
245  }
246  is \%h, $old, '\local %a unwound';
247  $old = \%i;
248  {
249    (\local %i) = \%ThatHash;
250    is \%i, \%ThatHash, '(\local %a)';
251  }
252  is \%i, $old, '(\local %a) unwound';
253}
254for (1,2) {
255  \state %y = {1,2},
256  \my %x = {1,2} if $_ == 1;
257  if ($_ == 2) {
258    is %x, 0, '\my %x = ... clears %x on scope exit';
259    is "@{[%y]}", "1 2", '\state %x = ... does not clear %x on scope exit';
260  }
261}
262
263# Subroutines
264
265package CodeTest {
266  BEGIN { *is = *main::is; }
267  use feature 'lexical_subs';
268  no warnings 'experimental::lexical_subs';
269  sub expect_scalar_cx { wantarray ? 0 : \&ThatSub }
270  sub expect_list_cx   { wantarray ? (\&ThatSub)x2 : 0 }
271  \&a = expect_scalar_cx;
272  is \&a, \&ThatSub, '\&pkg';
273  my sub a;
274  \&a = expect_scalar_cx;
275  is \&a, \&ThatSub, '\&mysub';
276  state sub as;
277  \&as = expect_scalar_cx;
278  is \&as, \&ThatSub, '\&statesub';
279  (\&b) = expect_list_cx;
280  is \&b, \&ThatSub, '(\&pkg)';
281  my sub b;
282  (\&b) = expect_list_cx;
283  is \&b, \&ThatSub, '(\&mysub)';
284  my sub bs;
285  (\&bs) = expect_list_cx;
286  is \&bs, \&ThatSub, '(\&statesub)';
287  \(&c) = expect_list_cx;
288  is \&c, \&ThatSub, '\(&pkg)';
289  my sub b;
290  \(&c) = expect_list_cx;
291  is \&c, \&ThatSub, '\(&mysub)';
292  my sub bs;
293  \(&cs) = expect_list_cx;
294  is \&cs, \&ThatSub, '\(&statesub)';
295
296  package main {
297    # this is only a problem in main:: due to 1e2cfe157ca
298    sub sx { "x" }
299    sub sy { "y" }
300    is sx(), "x", "check original";
301    my $temp = \&sx;
302    \&sx = \&sy;
303    is sx(), "y", "aliased";
304    \&sx = $temp;
305    is sx(), "x", "and restored";
306  }
307}
308
309# Mixed List Assignments
310
311(\$tahi, $rua) = \(1,2);
312is join(' ', $tahi, $$rua), '1 2',
313  'mixed scalar ref and scalar list assignment';
314$_ = 1;
315\($bb, @cc, %dd, &ee, $_==1 ? $ff : @ff, $_==2 ? $gg : @gg, (@hh)) =
316    (\$BB, \@CC, \%DD, \&EE, \$FF, \@GG, \1, \2, \3);
317is \$bb, \$BB, '\$scalar in list assignment';
318is \@cc, \@CC, '\@array in list assignment';
319is \%dd, \%DD, '\%hash in list assignment';
320is \&ee, \&EE, '\&code in list assignment';
321is \$ff, \$FF, '$scalar in \ternary in list assignment';
322is \@gg, \@GG, '@gg in \ternary in list assignment';
323is "@hh", '1 2 3', '\(@array) in list assignment';
324
325# Conditional expressions
326
327$_ = 3;
328$_ == 3 ? \$tahi : $rua = \3;
329is $tahi, 3, 'cond assignment resolving to scalar ref';
330$_ == 0 ? \$toru : $wha = \3;
331is $$wha, 3, 'cond assignment resolving to scalar';
332$_ == 3 ? \$rima : \$ono = \5;
333is $rima, 5, 'cond assignment with refgens on both branches';
334\($_ == 3 ? $whitu : $waru) = \5;
335is $whitu, 5, '\( ?: ) assignment';
336\($_ == 3 ? $_ < 4 ? $ii : $_ : $_) = \$_;
337is \$ii, \$_, 'nested \ternary assignment';
338
339# Foreach
340
341for \my $topic (\$for1, \$for2) {
342    push @for, \$topic;
343}
344is "@for", \$for1 . ' ' . \$for2, 'foreach \my $a';
345is \$topic, \$::topic, 'for \my scoping';
346
347@for = ();
348for \$::a(\$for1, \$for2) {
349    push @for, \$::a;
350}
351is "@for", \$for1 . ' ' . \$for2, 'foreach \$::a';
352
353@for = ();
354for \my @a([1,2], [3,4]) {
355    push @for, @a;
356}
357is "@for", "1 2 3 4", 'foreach \my @a [perl #22335]';
358
359@for = ();
360for \@::a([1,2], [3,4]) {
361    push @for, @::a;
362}
363is "@for", "1 2 3 4", 'foreach \@::a [perl #22335]';
364
365@for = ();
366for \my %a({5,6}, {7,8}) {
367    push @for, %a;
368}
369is "@for", "5 6 7 8", 'foreach \my %a [perl #22335]';
370
371@for = ();
372for \%::a({5,6}, {7,8}) {
373    push @for, %::a;
374}
375is "@for", "5 6 7 8", 'foreach \%::a [perl #22335]';
376
377@for = ();
378{
379  use feature 'lexical_subs';
380  no warnings 'experimental::lexical_subs';
381  my sub a;
382  for \&a(sub {9}, sub {10}) {
383    push @for, &a;
384  }
385}
386is "@for", "9 10", 'foreach \&padcv';
387
388@for = ();
389for \&::a(sub {9}, sub {10}) {
390  push @for, &::a;
391}
392is "@for", "9 10", 'foreach \&rv2cv';
393
394# Errors
395
396eval { my $x; \$x = 3 };
397like $@, qr/^Assigned value is not a reference at/, 'assigning non-ref';
398eval { my $x; \$x = [] };
399like $@, qr/^Assigned value is not a SCALAR reference at/,
400    'assigning non-scalar ref to scalar ref';
401eval { \$::x = [] };
402like $@, qr/^Assigned value is not a SCALAR reference at/,
403    'assigning non-scalar ref to package scalar ref';
404eval { my @x; \@x = {} };
405like $@, qr/^Assigned value is not an ARRAY reference at/,
406    'assigning non-array ref to array ref';
407eval { \@::x = {} };
408like $@, qr/^Assigned value is not an ARRAY reference at/,
409    'assigning non-array ref to package array ref';
410eval { my %x; \%x = [] };
411like $@, qr/^Assigned value is not a HASH reference at/,
412    'assigning non-hash ref to hash ref';
413eval { \%::x = [] };
414like $@, qr/^Assigned value is not a HASH reference at/,
415    'assigning non-hash ref to package hash ref';
416eval { use feature 'lexical_subs';
417       no warnings 'experimental::lexical_subs';
418       my sub x; \&x = [] };
419like $@, qr/^Assigned value is not a CODE reference at/,
420    'assigning non-code ref to lexical code ref';
421eval { \&::x = [] };
422like $@, qr/^Assigned value is not a CODE reference at/,
423    'assigning non-code ref to package code ref';
424
425eval { my $x; (\$x) = 3 };
426like $@, qr/^Assigned value is not a reference at/,
427    'list-assigning non-ref';
428eval { my $x; (\$x) = [] };
429like $@, qr/^Assigned value is not a SCALAR reference at/,
430    'list-assigning non-scalar ref to scalar ref';
431eval { (\$::x = []) };
432like $@, qr/^Assigned value is not a SCALAR reference at/,
433    'list-assigning non-scalar ref to package scalar ref';
434eval { my @x; (\@x) = {} };
435like $@, qr/^Assigned value is not an ARRAY reference at/,
436    'list-assigning non-array ref to array ref';
437eval { (\@::x) = {} };
438like $@, qr/^Assigned value is not an ARRAY reference at/,
439    'list-assigning non-array ref to package array ref';
440eval { my %x; (\%x) = [] };
441like $@, qr/^Assigned value is not a HASH reference at/,
442    'list-assigning non-hash ref to hash ref';
443eval { (\%::x) = [] };
444like $@, qr/^Assigned value is not a HASH reference at/,
445    'list-assigning non-hash ref to package hash ref';
446eval { use feature 'lexical_subs';
447       no warnings 'experimental::lexical_subs';
448       my sub x; (\&x) = [] };
449like $@, qr/^Assigned value is not a CODE reference at/,
450    'list-assigning non-code ref to lexical code ref';
451eval { (\&::x) = [] };
452like $@, qr/^Assigned value is not a CODE reference at/,
453    'list-assigning non-code ref to package code ref';
454
455eval '(\do{}) = 42';
456like $@, qr/^Can't modify reference to do block in list assignment at /,
457    "Can't modify reference to do block in list assignment";
458eval '(\pos) = 42';
459like $@,
460     qr/^Can't modify reference to match position in list assignment at /,
461    "Can't modify ref to some scalar-returning op in list assignment";
462eval '(\glob) = 42';
463like $@,
464     qr/^Can't modify reference to glob in list assignment at /,
465    "Can't modify reference to some list-returning op in list assignment";
466eval '\pos = 42';
467like $@,
468    qr/^Can't modify reference to match position in scalar assignment at /,
469   "Can't modify ref to some scalar-returning op in scalar assignment";
470eval '\(local @b) = 42';
471like $@,
472    qr/^Can't modify reference to localized parenthesized array in list(?x:
473      ) assignment at /,
474   q"Can't modify \(local @array) in list assignment";
475eval '\local(@b) = 42';
476like $@,
477    qr/^Can't modify reference to localized parenthesized array in list(?x:
478      ) assignment at /,
479   q"Can't modify \local(@array) in list assignment";
480eval '\local(@{foo()}) = 42';
481like $@,
482    qr/^Can't modify reference to array dereference in list assignment at/,
483   q"'Array deref' error takes prec. over 'local paren' error";
484eval '\(%b) = 42';
485like $@,
486    qr/^Can't modify reference to parenthesized hash in list assignment a/,
487   "Can't modify ref to parenthesized package hash in scalar assignment";
488eval '\(my %b) = 42';
489like $@,
490    qr/^Can't modify reference to parenthesized hash in list assignment a/,
491   "Can't modify ref to parenthesized hash (\(my %b)) in list assignment";
492eval '\my(%b) = 42';
493like $@,
494    qr/^Can't modify reference to parenthesized hash in list assignment a/,
495   "Can't modify ref to parenthesized hash (\my(%b)) in list assignment";
496eval '\%{"42"} = 42';
497like $@,
498    qr/^Can't modify reference to hash dereference in scalar assignment a/,
499   "Can't modify reference to hash dereference in scalar assignment";
500eval '$foo ? \%{"42"} : \%43 = 42';
501like $@,
502    qr/^Can't modify reference to hash dereference in scalar assignment a/,
503   "Can't modify ref to whatever in scalar assignment via cond expr";
504eval '\$0=~y///=0';
505like $@,
506    qr#^Can't modify transliteration \(tr///\) in scalar assignment a#,
507   "Can't modify transliteration (tr///) in scalar assignment";
508
509# Miscellaneous
510
511{
512  local $::TODO = ' ';
513  my($x,$y);
514  sub {
515    sub {
516      \$x = \$y;
517    }->();
518    is \$x, \$y, 'lexical alias affects outer closure';
519  }->();
520  is \$x, \$y, 'lexical alias affects outer sub where vars are declared';
521}
522
523{ # PADSTALE has a double meaning
524  use feature 'lexical_subs', 'signatures';
525  no warnings 'experimental';
526  my $c;
527  my sub s ($arg) {
528    state $x = ++$c;
529    if ($arg == 3) { return $c }
530    goto skip if $arg == 2;
531    my $y;
532   skip:
533    # $y is PADSTALE the 2nd time
534    \$x = \$y if $arg == 2;
535  }
536  s(1);
537  s(2);
538  is s(3), 1, 'padstale alias should not reset state'
539}
540
541SKIP: {
542    skip_without_dynamic_extension('List/Util');
543    require Scalar::Util;
544    my $a;
545    Scalar::Util::weaken($r = \$a);
546    \$a = $r;
547    pass 'no crash when assigning \$lex = $weakref_to_lex'
548}
549
550{
551    \my $x = \my $y;
552    $x = 3;
553    ($x, my $z) = (1, $y);
554    is $z, 3, 'list assignment after aliasing lexical scalars';
555}
556{
557    (\my $x) = \my $y;
558    $x = 3;
559    ($x, my $z) = (1, $y);
560    is $z, 3,
561      'regular list assignment after aliasing via list assignment';
562}
563{
564    my $y;
565    goto do_aliasing;
566
567   do_test:
568    $y = 3;
569    my($x,$z) = (1, $y);
570    is $z, 3, 'list assignment "before" aliasing lexical scalars';
571    last;
572
573   do_aliasing:
574    \$x = \$y;
575    goto do_test;
576}
577{
578    my $y;
579    goto do_aliasing2;
580
581   do_test2:
582    $y = 3;
583    my($x,$z) = (1, $y);
584    is $z, 3,
585     'list assignment "before" aliasing lex scalars via list assignment';
586    last;
587
588   do_aliasing2:
589    \($x) = \$y;
590    goto do_test2;
591}
592{
593    my @a;
594    goto do_aliasing3;
595
596   do_test3:
597    @a[0,1] = qw<a b>;
598    my($y,$x) = ($a[0],$a[1]);
599    is "@a", 'b a',
600       'aelemfast_lex-to-scalar list assignment "before" aliasing';
601    last;
602
603   do_aliasing3:
604    \(@a) = \($x,$y);
605    goto do_test3;
606}
607
608# Used to fail an assertion [perl #123821]
609eval '\(&$0)=0';
610pass("RT #123821");
611
612# Used to fail an assertion [perl #128252]
613{
614    no feature 'refaliasing';
615    use warnings;
616    eval q{sub{\@0[0]=0};};
617    pass("RT #128252");
618}
619
620# RT #133538 slices were inadvertently always localising
621
622{
623    use feature 'refaliasing';
624    no warnings 'experimental';
625
626    my @src = (100,200,300);
627
628    my @a = (1,2,3);
629    my %h = qw(one 10 two 20 three 30);
630
631    {
632        use feature 'declared_refs';
633        local \(@a[0,1,2]) = \(@src);
634        local \(@h{qw(one two three)}) = \(@src);
635        $src[0]++;
636        is("@a", "101 200 300", "rt #133538 \@a aliased");
637        is("$h{one} $h{two} $h{three}", "101 200 300", "rt #133538 %h aliased");
638    }
639    is("@a", "1 2 3", "rt #133538 \@a restored");
640    is("$h{one} $h{two} $h{three}", "10 20 30", "rt #133538 %h restored");
641
642    {
643        \(@a[0,1,2]) = \(@src);
644        \(@h{qw(one two three)}) = \(@src);
645        $src[0]++;
646        is("@a", "102 200 300", "rt #133538 \@a aliased try 2");
647        is("$h{one} $h{two} $h{three}", "102 200 300",
648                "rt #133538 %h aliased try 2");
649    }
650    $src[2]++;
651    is("@a", "102 200 301", "rt #133538 \@a still aliased");
652    is("$h{one} $h{two} $h{three}", "102 200 301", "rt #133538 %h still aliased");
653
654}
655