Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Hash dereferencing in a loop

by willjones (Sexton)
on Jun 07, 2013 at 16:32 UTC ( #1037703=perlquestion: print w/replies, xml ) Need Help??

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

I get the following error message when I try to compile this code with use strict turned on:

sub failsToCompile { my $hashRef = shift; my $val; foreach my $key (keys %$hashRef) { $val .= $hashRef{$key}; } return $val; }
Error Message: Global symbol "%hashRef" requires explicit package name ...

I finally discovered a work around. When I rework the code a little to be like the following sub then the error message goes away. So, I know how to get around it now, but my question is... why? Why do I have to do that? Why can't I refer to the hash that the hash reference points to in the for loop without dereferencing it first and assigning it to another variable as I did in the following sub? Also, what is making perl think this is a global symbol? Thanks in advance for input/explanations.

sub worksCompilingFine { my $hashRef = shift; my %hash = %$hashRef; my $val; foreach my $key (keys %hash) { $val .= $hash{$key}; } return $val; }

Replies are listed 'Best First'.
Re: Hash dereferencing in a loop
by roboticus (Chancellor) on Jun 07, 2013 at 16:46 UTC


    The problem you're having is that $hashRef is a reference to a hash, it's not a hash itself:

    my %hash = (a=>1, b=>2); my $hashRef = { c=>3, d=>4 }; # For a hash, you can reference the item as you expect: my $v = $hash{a}; # For a hash ref, you need to either use a double $, or # use an arrow: $v = $hashRef->{c}; $v = $$hashRef{c};

    You can use a reference to manipulate a hash, too:

    # Get a reference to %hash $hashRef = \%hash; $v = $hashRef->{a}; # $v now holds 1


    When your only tool is a hammer, all problems look like your thumb.

Re: Hash dereferencing in a loop
by hdb (Monsignor) on Jun 07, 2013 at 16:42 UTC

    In your first version  $hashRef{$key}, you make use of %hashRef which is not declared. Change it to  $hashRef->{$key} and you should be fine. No need to do a copy as in your workaround which would be wasteful if the hash is large.

      Also, you may encounter “double-$” syntax:   $$hashref{$key}.

      The two are equivalent, and notice in this case that the -> symbol does not appear.   Recommend that you consistently use one or the other (your choice) in your programs.   (Double-$ is less common.)

      Also note that, in cases where a sequence of -> symbols would technically be required, to reference elements of a hashref that contains hashrefs, Perl allows the additional ones to be omitted.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1037703]
Front-paged by Arunbear
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (5)
As of 2020-04-05 21:07 GMT
Find Nodes?
    Voting Booth?
    The most amusing oxymoron is:

    Results (35 votes). Check out past polls.