for my $id (@selected) { $list{$id}{selected} = 1; } for my $key (keys %list) { print qq(<li name="$key"); print ' class="selected"' if $list{$key}{selected}; print ">$list{$key}\n"; }
Wait, what's going on? We test for $list{$key}{selected}, so $list{$key} is a hash reference. Then, we print $list{$key} - but in the output, we do not get any HASH(0x2561a68), but the correct goods' names. I asked a coworker, and she told me this part of the script was "dark magic"; she had debugged it once and still remembered the value was coming out even if it should not. I played a bit with the script to remember I have already seen a similar behaviour: of course, the script does not use strict! Try yourself:
#!/usr/bin/perl # Script part 1. use warnings; use strict; my $code = << '__CODE__'; %list = ( scalar => 'Plain', ref => 'Overwritten' ); $list{ref}{selected} = 1; for my $key (keys %list) { print "$key: $list{$key}"; print " - Selected" if $list{$key}{selected}; print "\n"; } __CODE__ { no strict; my %list; eval $code; print "Wow: $Overwritten{selected}\n"; }
The last print explains what happens: Perl sees you are trying to use $list{ref} as a hash reference, while its value is the string "Overwritten". It therefore creates a hash of that name for you (even more funny if the string contains spaces).
So far, so good. Lesson learnt: the people who tell you "use strict" know what they say. I tried to explain to the coworkers what the problem was, but those not familiar with Perl were not able to understand.
But then, I thought to myself: Is it possible to make the code work even under strict? tie and overload would probably be useful, as I remembered from Programming Perl. And after several minutes, I was able to run the code under strict. You can test your skills before revealing my solution:
Just for completness, this is the "common" behaviour I expected at the beginning:
# Script part 3. { my %list; eval "$code;1" or die $@; }
Note: The three last code examples should be kept in one file.
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |