Historically, Perl supports lexical scoping of variables, allowing the use of closures — functions that retain their external environment. The problem arises when a closure references variables outside its scope or when nested structures create cyclic references, leading to memory leaks due to careless handling of references.
The solution is to use closures to create function factories and functional style, while remembering to manage references correctly when closing over variables from an external scope.
Code example:
sub make_counter { my $count = 0; return sub { $count++; }; } my $counter = make_counter(); print $counter->(), "\n"; # 0 print $counter->(), "\n"; # 1
Key features:
What happens if you return an anonymous function that references itself?
A cyclic reference will be created, which Perl cannot automatically collect with the garbage collector. This will lead to a memory leak. To resolve this, use weak references, module Scalar::Util:
use Scalar::Util qw(weaken); my $foo; $foo = sub { ... $foo ... }; weaken($foo);
Does a closure always capture a "copy" of the variable, or is it a reference to the same variable?
A closure always operates on the current variable, its scope is fixed at the time of closure creation. Thus, the variable is the same for all calls to the closure function.
Can a closure work with mutable state outside of itself without holding a strong reference to it?
Yes, use weak references (Scalar::Util::weaken) or structure your code so that references are held only where they are needed (for example, pass data from outside with each closure call).
Created a callback closure that captures $self from an OO object and holds inside a hash of callbacks. After the object is destroyed, memory is not freed.
Pros:
Cons:
Closure correctly weakly references $self using Scalar::Util::weaken:
use Scalar::Util qw(weaken); my $cb = sub { my $self = shift; weaken($self); ... };
Pros:
Cons: