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

Hello Monks,

It's been a while since I last coded anything (a loooong while, I'm afraid) and it would appear that I need a bit of help to make my coding-starved brain process even the most basic of problems. Here we go...

I've got a subroutine that processes a number of items in a list. The items are all names of hashes. For example:

foreach (qw/hasha hashb hashc/) { @keys = keys %$_; print "There are @keys here"; }

But this attempt doesn't work and results in

Can't use string ("%Blog::Entry::") as a HASH ref while "strict refs" +in use at ./blog.pl line 18.

Would someone please explain to me a) why this is and b) how I might go about accomplishing this better?

Thank you!

Replies are listed 'Best First'.
Re: Using the value of a scalar as a hash
by sgifford (Prior) on Aug 17, 2005 at 20:29 UTC
    The exact answer to your question is to wrap this code in a block with strict refs turned off:
    { no strict 'refs'; foreach (qw/hasha hashb hashc/) { @keys = keys %$_; print "There are @keys here"; } }

    But the better answer is a question: why are you doing this? Why not just store the data in one hash to begin with, for example $hash{a}{key1} instead of $hasha{key1}?

Re: Using the value of a scalar as a hash
by davidrw (Prior) on Aug 17, 2005 at 20:33 UTC
    well, eval can do this, but comes with the usual caveats that a) you have to trust the strings you give it and b) there's probably a better approach ..
    foreach (qw/hasha hashb hashc/) { @keys = keys eval('%' . $_); print "There are " . scalar(@keys) . " keys here for '$_'\n"; }
    As for a better approach, first thought is that those hashes should originally be constructed as hashrefs and in a hash...
    my %big_data = ( hasha => \%hasha, hashb => \%hashb, hashc => \%hashc, ); foreach (qw/hasha hashb hashc/) { @keys = keys %{$big_data{$_}}; print "There are " . scalar(@keys) . " keys here for '$_'\n"; }