wardk asked:
In the code you list, the hash is created via my in the sub, yet it's available outside the sub when the sub ends. I assume that it's not destroyed when the subroutine ends because it's still being referenced?
Your assumption is correct. Variables are garbage collected when their reference count drops to zero. When the hash in the sub is declared with my, it has a reference count of one. When the reference to it is created, that reference has a reference count of one and the hash (now referred to as the "referent", or thing being referred to) has a reference of two. When the reference is returned, the original variable goes out of scope, setting the reference count down to one again.
Note that there are two reference counts here. The $hash_ref variable has a reference count (at that point) of one and the referent (the hash we were pointing to) has a reference of one. Got that? It takes a while to get it all straight, but the process is fairly straightforward.
wardk also wrote:
my first inclination would be to create the hash and pass a reference into the sub, assuming that would ensure it's availablity when the sub ends.
There are two difficulties with that approach. The first is that this is atypical behavior that tends to confuse newer programmers. For example, how many times have you seen someone ask what is wrong with this:
$var = chomp $var;
That usually sets $var to 1 (one) because chomp returns the number of characters removed. Most perl functions take an argument but don't change it.
The other problem is code that quietly munges its arguments can cause all sorts of bugs for the unwary. For example, what if you passed in a hash that already had data and were expecting another one returned? That sort of stuff is very easy to misunderstand. Typical behavior for subroutines is to copy the arguments into new, non-aliased variables, do their stuff, and then return the results.
Cheers,
Ovid
Join the Perlmonks Setiathome Group or just click on the the link and check out our stats. |