my %drink;
# other attribute hashes
sub set {
my ($key, $attr, $value) = @_;
my $hashref;
eval "\$hashref = \\\%$attr";
if ( !defined $hashref ) {
carp 'Invalid attribute name';
}
else {
$hashref->{$key} = $value;
}
}
The call to this subroutine:
set('larry', 'drink', 'Old Speckled Hen');
This does not work, i.e. it does not actually alter the 'real' hash (%drink).
I have discover two fixes, but I cannot explain why either works
1. If I stringify the actual hash (%drink). After the assignment, if I add:
print "$drink{$key}\n";
it works. It seems to 'commit' $hashref. Using Data::Dumper or Devel::Peek::Dump also fixes it.
2. If I make the hash an 'our' variable it works.
I'm setting warnings and use strict. Tried on 5.8.6 on Fedora and 5.8.7 on Windows.
What is going on?
I don't understand why this doesn't work, but I do have a suggestion about how to fix it. Instead of using seperate hashes with different names, have a hash of hashrefs. Then you don't need an eval STRING or symbolic references to make it work.
By the time the eval STRING code runs, lexicals don't really have names anymore, so Perl can't look them up by name.
It seems your simplified fragment is not demonstrating the problem, because:
#!/usr/bin/perl -w
# Strict
use strict;
use warnings;
# Libraries
use Carp;
use Data::Dumper;
my %drink;
# other attribute hashes
set('larry', 'drink', 'Old Speckled Hen');
print $drink{'larry'}, "\n";
# print "Dump(\%drink) => [%s]\n", Dumper(\%drink);
sub set {
my ($key, $attr, $value) = @_;
my $hashref;
eval "\$hashref = \\\%$attr";
if ( !defined $hashref ) {
carp 'Invalid attribute name';
}
else {
$hashref->{$key} = $value;
}
}
is working for me:
% prog541345.pl Old Speckled HenIf that isn't what you're getting, please compare the above code fragment (based on what you provided in your post) to your actual code, and see if that helps locate the problem.
perlmonks.org content © perlmonks.org and cdarke, chromatic, liverpole, theorbtwo
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03