13 my @comma = ("key", "value");
15 # The peephole optimiser already knows that it should convert the string in
16 # $foo{string} into a shared hash key scalar. It might be worth making the
17 # tokeniser build the LHS of => as a shared hash key scalar too.
18 # And so there's the possiblility of it going wrong
19 # And going right on 8 bit but wrong on utf8 keys.
20 # And really we should also try utf8 literals in {} and => in utf8.t
22 # Some of these tests are (effectively) duplicated in each.t
24 ok (keys %comma == 1, 'keys on comma hash');
25 ok (values %comma == 1, 'values on comma hash');
26 # defeat any tokeniser or optimiser cunning
28 is ($comma{"k" . $key}, "value", 'is key present? (unoptimised)');
30 is ($comma{key}, "value", 'is key present? (maybe optimised)');
31 #tokeniser may treat => differently.
32 my @temp = (key=>undef);
33 is ($comma{$temp[0]}, "value", 'is key present? (using LHS of =>)');
36 ok (eq_array (\@comma, \@temp), 'list from comma hash');
39 ok (eq_array (\@comma, \@temp), 'first each from comma hash');
41 ok (eq_array ([], \@temp), 'last each from comma hash');
45 ok (keys %temp == 1, 'keys on copy of comma hash');
46 ok (values %temp == 1, 'values on copy of comma hash');
47 is ($temp{'k' . $key}, "value", 'is key present? (unoptimised)');
49 is ($temp{key}, "value", 'is key present? (maybe optimised)');
51 is ($comma{$temp[0]}, "value", 'is key present? (using LHS of =>)');
54 ok (eq_array (\@temp, \@temp), 'list from copy of comma hash');
57 ok (eq_array (\@temp, \@temp), 'first each from copy of comma hash');
59 ok (eq_array ([], \@temp), 'last each from copy of comma hash');
61 my @arrow = (Key =>"Value");
64 ok (keys %arrow == 1, 'keys on arrow hash');
65 ok (values %arrow == 1, 'values on arrow hash');
66 # defeat any tokeniser or optimiser cunning
68 is ($arrow{"K" . $key}, "Value", 'is key present? (unoptimised)');
70 is ($arrow{Key}, "Value", 'is key present? (maybe optimised)');
71 #tokeniser may treat => differently.
72 @temp = ('Key', undef);
73 is ($arrow{$temp[0]}, "Value", 'is key present? (using LHS of =>)');
76 ok (eq_array (\@arrow, \@temp), 'list from arrow hash');
79 ok (eq_array (\@arrow, \@temp), 'first each from arrow hash');
81 ok (eq_array ([], \@temp), 'last each from arrow hash');
85 ok (keys %temp == 1, 'keys on copy of arrow hash');
86 ok (values %temp == 1, 'values on copy of arrow hash');
87 is ($temp{'K' . $key}, "Value", 'is key present? (unoptimised)');
89 is ($temp{Key}, "Value", 'is key present? (maybe optimised)');
90 @temp = ('Key', undef);
91 is ($arrow{$temp[0]}, "Value", 'is key present? (using LHS of =>)');
94 ok (eq_array (\@temp, \@temp), 'list from copy of arrow hash');
97 ok (eq_array (\@temp, \@temp), 'first each from copy of arrow hash');
99 ok (eq_array ([], \@temp), 'last each from copy of arrow hash');
101 my %direct = ('Camel', 2, 'Dromedary', 1);
103 $slow{Dromedary} = 1;
106 ok (eq_hash (\%slow, \%direct), "direct list assignment to hash");
107 %direct = (Camel => 2, 'Dromedary' => 1);
108 ok (eq_hash (\%slow, \%direct), "direct list assignment to hash using =>");
110 $slow{Llama} = 0; # A llama is not a camel :-)
111 ok (!eq_hash (\%direct, \%slow), "different hashes should not be equal!");
113 my (%names, %names_copy);
114 %names = ('$' => 'Scalar', '@' => 'Array', # Grr '
115 '%', 'Hash', '&', 'Code');
116 %names_copy = %names;
117 ok (eq_hash (\%names, \%names_copy), "check we can copy our hash");
121 return eq_hash (\%names, \%args);
124 ok (in (%names), "pass hash into a method");
129 return eq_hash (\%names, \%args);
132 ok (main->in_method (%names), "pass hash into a method");
137 %names_copy = out ();
139 ok (eq_hash (\%names, \%names_copy), "pass hash from a subroutine");
145 %names_copy = main->out_method ();
147 ok (eq_hash (\%names, \%names_copy), "pass hash from a method");
153 %names_copy = in_out (%names);
155 ok (eq_hash (\%names, \%names_copy), "pass hash to and from a subroutine");
162 %names_copy = main->in_out_method (%names);
164 ok (eq_hash (\%names, \%names_copy), "pass hash to and from a method");
166 my %names_copy2 = %names;
167 ok (eq_hash (\%names, \%names_copy2), "check copy worked");
169 # This should get ignored.
170 %names_copy = ('%', 'Associative Array', %names);
172 ok (eq_hash (\%names, \%names_copy), "duplicates at the start of a list");
175 %names_copy = ('*', 'Typeglob', %names);
177 $names_copy2{'*'} = 'Typeglob';
178 ok (eq_hash (\%names_copy, \%names_copy2), "duplicates at the end of a list");
180 %names_copy = ('%', 'Associative Array', '*', 'Endangered species', %names,
183 ok (eq_hash (\%names_copy, \%names_copy2), "duplicates at both ends");
187 foreach my $chr (60, 200, 600, 6000, 60000) {
188 # This little game may set a UTF8 flag internally. Or it may not. :-)
189 my ($key, $value) = (chr ($chr) . "\x{ABCD}", "$chr\x{ABCD}");
191 my @utf8c = ($key, $value);
194 ok (keys %utf8c == 1, 'keys on utf8 comma hash');
195 ok (values %utf8c == 1, 'values on utf8 comma hash');
196 # defeat any tokeniser or optimiser cunning
197 is ($utf8c{"" . $key}, $value, 'is key present? (unoptimised)');
198 my $tempval = sprintf '$utf8c{"\x{%x}"}', $chr;
199 is (eval $tempval, $value, "is key present? (maybe $tempval is optimised)");
200 $tempval = sprintf '@temp = ("\x{%x}" => undef)', $chr;
201 eval $tempval or die "'$tempval' gave $@";
202 is ($utf8c{$temp[0]}, $value, 'is key present? (using LHS of $tempval)');
205 ok (eq_array (\@utf8c, \@temp), 'list from utf8 comma hash');
208 ok (eq_array (\@utf8c, \@temp), 'first each from utf8 comma hash');
210 ok (eq_array ([], \@temp), 'last each from utf8 comma hash');
214 ok (keys %temp == 1, 'keys on copy of utf8 comma hash');
215 ok (values %temp == 1, 'values on copy of utf8 comma hash');
216 is ($temp{"" . $key}, $value, 'is key present? (unoptimised)');
217 $tempval = sprintf '$temp{"\x{%x}"}', $chr;
218 is (eval $tempval, $value, "is key present? (maybe $tempval is optimised)");
219 $tempval = sprintf '@temp = ("\x{%x}" => undef)', $chr;
220 eval $tempval or die "'$tempval' gave $@";
221 is ($temp{$temp[0]}, $value, "is key present? (using LHS of $tempval)");
224 ok (eq_array (\@temp, \@temp), 'list from copy of utf8 comma hash');
227 ok (eq_array (\@temp, \@temp), 'first each from copy of utf8 comma hash');
229 ok (eq_array ([], \@temp), 'last each from copy of utf8 comma hash');
231 my $assign = sprintf '("\x{%x}" => "%d")', $chr, $chr;
233 my (@utf8a) = eval $assign;
236 ok (keys %utf8a == 1, 'keys on utf8 arrow hash');
237 ok (values %utf8a == 1, 'values on utf8 arrow hash');
238 # defeat any tokeniser or optimiser cunning
239 is ($utf8a{$key . ""}, $value, 'is key present? (unoptimised)');
240 $tempval = sprintf '$utf8a{"\x{%x}"}', $chr;
241 is (eval $tempval, $value, "is key present? (maybe $tempval is optimised)");
242 $tempval = sprintf '@temp = ("\x{%x}" => undef)', $chr;
243 eval $tempval or die "'$tempval' gave $@";
244 is ($utf8a{$temp[0]}, $value, "is key present? (using LHS of $tempval)");
247 ok (eq_array (\@utf8a, \@temp), 'list from utf8 arrow hash');
250 ok (eq_array (\@utf8a, \@temp), 'first each from utf8 arrow hash');
252 ok (eq_array ([], \@temp), 'last each from utf8 arrow hash');
256 ok (keys %temp == 1, 'keys on copy of utf8 arrow hash');
257 ok (values %temp == 1, 'values on copy of utf8 arrow hash');
258 is ($temp{'' . $key}, $value, 'is key present? (unoptimised)');
259 $tempval = sprintf '$temp{"\x{%x}"}', $chr;
260 is (eval $tempval, $value, "is key present? (maybe $tempval is optimised)");
261 $tempval = sprintf '@temp = ("\x{%x}" => undef)', $chr;
262 eval $tempval or die "'$tempval' gave $@";
263 is ($temp{$temp[0]}, $value, "is key present? (using LHS of $tempval)");
266 ok (eq_array (\@temp, \@temp), 'list from copy of utf8 arrow hash');
269 ok (eq_array (\@temp, \@temp), 'first each from copy of utf8 arrow hash');
271 ok (eq_array ([], \@temp), 'last each from copy of utf8 arrow hash');
275 # now some tests for hash assignment in scalar and list context with
276 # duplicate keys [perl #24380], [perl #31865]
278 my %h; my $x; my $ar;
279 is( (join ':', %h = (1) x 8), '1:1',
280 'hash assignment in list context removes duplicates' );
281 is( (join ':', %h = qw(a 1 a 2 b 3 c 4 d 5 d 6)), 'a:2:b:3:c:4:d:6',
282 'hash assignment in list context removes duplicates 2' );
283 is( scalar( %h = (1,2,1,3,1,4,1,5) ), 8,
284 'hash assignment in scalar context' );
285 is( scalar( ($x,%h) = (0,1,2,1,3,1,4,1,5) ), 9,
286 'scalar + hash assignment in scalar context' );
287 $ar = [ %h = (1,2,1,3,1,4,1,5) ];
288 is( $#$ar, 1, 'hash assignment in list context' );
289 is( "@$ar", "1 5", '...gets the last values' );
290 $ar = [ ($x,%h) = (0,1,2,1,3,1,4,1,5) ];
291 is( $#$ar, 2, 'scalar + hash assignment in list context' );
292 is( "@$ar", "0 1 5", '...gets the last values' );
295 # test stringification of keys
298 my @types = qw( SCALAR ARRAY HASH CODE GLOB);
299 my @refs = ( \ do { my $x }, [], {}, sub {}, \ *x);
302 @expect{map "$_", @refs} = @types;
303 ok (eq_hash(\%h, \%expect), 'unblessed ref stringification');
306 %h = (); %expect = ();
308 @expect{map "$_", @refs} = @types;
309 ok (eq_hash(\%h, \%expect), 'blessed ref stringification');
312 # [perl #76716] Hash assignment should not zap weak refs.
314 skip_if_miniperl("no dynamic loading on miniperl, no Scalar::Util", 2);
316 require Scalar::Util;
317 Scalar::Util::weaken(my $p = \%tb);
319 is $p, \%tb, "hash assignment should not zap weak refs";
321 is $p, \%tb, "hash undef should not zap weak refs";
324 # test odd hash assignment warnings
327 warning_like(sub {%h = (1..3)}, qr/^Odd number of elements in hash assignment/);
328 warning_like(sub {%h = ({})}, qr/^Reference found where even-sized list expected/);
330 warning_like(sub { ($s, %h) = (1..4)}, qr/^Odd number of elements in hash assignment/);
331 warning_like(sub { ($s, %h) = (1, {})}, qr/^Reference found where even-sized list expected/);
334 # hash assignment in scalar and list context with odd number of elements
336 no warnings 'misc', 'uninitialized';
338 is( join( ':', %h = (1..3)), '1:2:3:',
339 'odd hash assignment in list context' );
340 ok( eq_hash( \%h, {1 => 2, 3 => undef} ), "correct value stored" );
341 is( scalar( %h = (1..3) ), 3,
342 'odd hash assignment in scalar context' );
343 ok( eq_hash( \%h, {1 => 2, 3 => undef} ), "correct value stored" );
344 is( join(':', ($x,%h) = (0,1,2,3) ), '0:1:2:3:',
345 'scalar + odd hash assignment in list context' );
346 ok( eq_hash( \%h, {1 => 2, 3 => undef} ), "correct value stored" );
347 is( scalar( ($x,%h) = (0,1,2,3) ), 4,
348 'scalar + odd hash assignment in scalar context' );
349 ok( eq_hash( \%h, {1 => 2, 3 => undef} ), "correct value stored" );
352 # hash assignment in scalar and list context with odd number of elements
355 no warnings 'misc', 'uninitialized';
357 is( (join ':', %h = (1,1,1)), '1:',
358 'odd hash assignment in list context with duplicates' );
359 ok( eq_hash( \%h, {1 => undef} ), "correct value stored" );
360 is( scalar(%h = (1,1,1)), 3,
361 'odd hash assignment in scalar context with duplicates' );
362 ok( eq_hash( \%h, {1 => undef} ), "correct value stored" );
363 is( join(':', ($x,%h) = (0,1,1,1) ), '0:1:',
364 'scalar + odd hash assignment in list context with duplicates' );
365 ok( eq_hash( \%h, {1 => undef} ), "correct value stored" );
366 is( scalar( ($x,%h) = (0,1,1,1) ), 4,
367 'scalar + odd hash assignment in scalar context with duplicates' );
368 ok( eq_hash( \%h, {1 => undef} ), "correct value stored" );