Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
Then me thinks you have some other bug making you think the hash isn't empty. Actually blindly following the advice given so far has caused some additional problems, namely scoping issues.

Lets examine a quick example:

#!/usr/bin/perl use strict; use warnings; use vars qw(%hash); sub foo { $hash{$_[0]}+=3; } sub bar { $hash{$_[0]}++; foo($_[0]); } foreach my $i (0..10) { my %hash; $hash{$i} = $i*3; bar($i); foo($i); foreach my $j (sort keys %hash) { print "hash{$j} = $hash{$j}\n"; } } print "done\n"; foreach my $j (sort keys %hash) { print "hash{$j} = $hash{$j}\n"; }
Ok, it looks a bit convoluted, definitely contrived, but hey it's just an example. Running through the program through our brains, we're creating a hash with a key of 0 to 10, and setting its value to 3*x, then calling bar() using that index. Bar increments that hash element x by one, then calls foo() which adds 3 more so the value of %hash{0} at this point should be 4. Then we call foo() again, so we're up to 7. %hash{1} should similarly get a value of 3+1+3+3=10 etc.

Oh, and each time through we should end up with a new empty hash too, so if we see repeaters, then the hash is sticking around

Run the code and we get this output:

hash{0} = 0 hash{1} = 3 hash{2} = 6 hash{3} = 9 hash{4} = 12 hash{5} = 15 hash{6} = 18 hash{7} = 21 hash{8} = 24 hash{9} = 27 hash{10} = 30 done hash{0} = 7 hash{1} = 7 hash{10} = 7 hash{2} = 7 hash{3} = 7 hash{4} = 7 hash{5} = 7 hash{6} = 7 hash{7} = 7 hash{8} = 7 hash{9} = 7
Well that wasn't what we expected was it. We don't have any repeaters, so we are getting a new hash, but the values aren't correct. And why do we have a %hash with values in it to print at the end?

Scoping is causing issues for you. Neither foo() nor bar() know anything about the private %hash we created by the "my %hash;" line within the foreach loop. bar() is creating a new global version of that hash and hash entry when you call it, and foo() is likewise acting on that new global version of %hash. That is why the initially printed values are only multiplied by three and the remaining global %hash all have values of 7 once you're out of the foreach loop .

So, how do you fix the problem? Either don't use "my %hash;", and continue to use a global %hash variable (not really recommended, but it works) or start passing a reference to the hash to the subroutines that need to access it. If you don't use "my %hash", then the "undef %hash;" line will be needed at the end of your foreach loop.

Update: You can't use a "my %hash" in this case, as you can't take a reference to a my variable (at least I'm pretty sure you can't) since it doesn't exist on the glob table like a normal variable does. Just add the "undef %hash;" at the end of the foreach loop and it should start working more correctly than it currently does.

-Scott

Update: Fixed various typo's... Update 2: Made the explaination a bit more clear, and fixed the "reference" idea


In reply to Re^3: re-useing a hash by 5mi11er
in thread re-useing a hash by ministry

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2024-03-28 22:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found