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.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Can you use string as a HASH ref while "strict refs" in use?
by LanX (Saint) on Dec 06, 2013 at 01:12 UTC | |
|
Re: Can you use string as a HASH ref while "strict refs" in use?
by Anonymous Monk on Dec 06, 2013 at 03:26 UTC |