++ Ovid
I like how you tend to write answers to code questions while keeping your eye on the big picture. If I were working on a project with other coders, I would be absolutely thrilled if some of them were as careful and aware as you are.
I think that sometimes Perl needs the extra diligence, not because of any inherent design flaw, but because it's so flexible and doesn't enforce very strict type checking. Anyway, nice post. | [reply] |
ovid,
One question...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?
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.
(Aparently I am assuming wrong, and have learned a new thing! :)
| [reply] |
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. | [reply] [d/l] |