swares has asked for the wisdom of the Perl Monks concerning the following question:

I am reading in data from a db trying to reconstruct a hash which has a hash reference in it. What I'm getting is a hash with an anonymous hash in it rather than a hash reference, I believe.
How do I get the right data structure? Here is what the data looks like printed: -- What I Get (BAD) -- [print_rnd_line](^!rob),swares,swares!chatzilla@pendulum-A127A504.wecm +.ibm.com,ARRAY(0x9a9e090),#bots2,{ 'file' => '/home/issuebot/data/rob.txt', },!rob -- What I Need (GOOD) -- [print_rnd_line](^!rob),swares,swares!chatzilla@pendulum-A127A504.wecm +.ibm.com,ARRAY(0x9ab13c8),#bots2,HASH(0x9a4ad0c),!rob [Hal] Got Text [!rob] Here is a code snippet of the offending code: while ((@row) = $sth->fetchrow_array) { $line= join(";", map {defined $_ ? $_ : "(null)"} @row); ($id, $name, $command, $reply_to, $listen_on, $requires, $help +, $description, $sub_name, $args, $sub_code, $whenactive, $enabled, $ +subscribed)=split /;/,$line; print "[load_plugins] Config $id, $name, $command, $reply_to, +$listen_on, $requires, $help, $description, $sub_name, $args, $sub_co +de, $whenactive, $enabled, $subscribed\n"; # subscriber handler my (@subscribed) = split /[\s|\n]+/, $subscribed; foreach my $subscrber (@subscribed){ if ($subscrber =~ /$identity_id/){$subscribed="true";last} +; } if ($subscribed !~ /true/){next}; if ($enabled =~ /true/){ # fix $args hash ref # $args needs to be a reference $public_handlers{"$name"} = ( { id => $id, name => "$name", command => "$command", reply_to => "$reply_to", listen_on => "$listen_on", requires => "$requires", help => "$help", description => "$description", sub => "$sub_name", args => "$args", sub_code => "$sub_code", whenactive => "$whenactive", enabled => "$enabled", }, );

Replies are listed 'Best First'.
Re: Need a hand with rebuilding hashes out of a db.
by Jenda (Abbot) on Apr 04, 2007 at 09:17 UTC

    THIS IS NOT A SHELL SCRIPT! DON'T ENCLOSE VARIABLES IN DOUBLEQUOTES!

    Sorry for screaming, but foo( "$varname") or $hash{"$varname"} is a sure sign you misunderstood something. And you are begging for problems. If the variable contains a number, then by enclosing it in double quotes you force perl to convert it to a string and make a copy of that string. If it's already a string you only make a copy. Just a waste, BUT if it's a reference you kill the reference. The thing you end up with will no longer be a reference. It will be just a string that will look a bit as if it was a reference but it will not work:

    my %h = (a => 5, b => 9); my $ref = \%h; print "\$ref->{a}=$ref->{a}\n"; my $not_ref = "$ref"; print "\$not_ref->{a}=$not_ref->{a}\n"; print "Even though $ref == $not_ref\n";

    While there are valid reasons to force stringification to a variable, they are very very rare! So please drop all your doublequotes around your variables!

    Update: Anno is right, $ref == $not_ref evaluates to false, $ref eq $not_ref would evaluate to true. I meant

    print "Even though $ref looks like $not_ref\n";
    I should have written it like that.

      You meant to say
      print "Even though $ref eq $not_ref\n";
      Anno