Unlike some other languages, Perl performs automatic garbage collection. Say you've defined a variable my $str = 'Hello world' then that needs to be stored in memory somewhere. When the variable goes out of scope, and Perl knows that it's not going to be used again, Perl's garbage collector can free the area of memory it was being stored in (so that the memory can be used for storing something else).
In some cases you end up with circular references:
my $a = [];
my $b = [ $a ];
push @$a, $b;
# Now $b contains a reference to $a and
# $a contains a reference to $b.
OK, that's a contrived example, but circular references do come up in real code all the time:
sub marry
{
my ($husband, $wife) = @_;
$husband->set_spouse($wife);
$wife->set_spouse($husband);
$wife->parent[0]->pay_for_party;
}
Now perhaps the $wife object contains a reference to $husband and vice versa.
In cases like this, Perl's garbage collector perhaps considers freeing the memory used by $wife but sees that $wife is still being referred to by $husband, so it can't free that memory until $husband is destroyed. But when it considers freeing the memory used by $husband it sees that $husband is being referred to be $wife, so it can't free anything there either.
Technically the way Perl does this is by maintaining a "reference count" for each thing that's in memory - in other words, a count of how many variables and references are pointing at it.
This catch-22 situation prevents either of the objects being freed from memory until the program exits. In short-running programs, this is often not a problem. But for long-running processes, it results in a memory leak - the program's memory consumption grows and grows over time.
weaken (found in the Scalar::Util package, which has been bundled with Perl seince 5.7.3) breaks the catch-22. It allows you to mark a reference as "weak" in which case it won't count towards the reference count.
As somebody else pointed out, in the original code (but not your cut-down example), $wrapper forms a closure over itself, which is a type of circular reference. This will result in memory leaking each time once is called. (Though judging by the function name, it is presumably only called once?) Thus weaken is used to break the circularity (as far as the garbage collector is concerned), and prevent a memory leak. |