Tom Molesworth > Closure-Explicit-0.001 > Closure::Explicit



Annotate this POD


View/Report Bugs
Module Version: 0.001   Source  


Closure::Explicit - check coderefs for variable capture


version 0.001


 use Closure::Explicit qw(callback);

   package Example;
   sub new { my $class = shift; bless {}, $class }
   sub method { my $self = shift; print "In method\n" }
 my $self = Example->new;
 # This will raise an exception due to the reference to $self
 eval {
   my $code = callback {
 # This will not raise the exception because $self is whitelisted
 my $code = callback {
 } [qw($self)];
 # This will wrap the coderef so we can pass a weakened copy of $self
 my $code = callback {
   my $self = shift;
 } weaken => [qw($self)];


Attempts to provide some very basic protection against unintentional capturing of lexicals in a closure.

For example, code such as the following risks creating cycles which mean the top-level object is never freed:

 sub some_method {
   my $self = shift;
   $self->{callback} = sub { $self->other_method }

and this can in turn lead to memory leaks.


The main "callback" function is not expected to change in future versions, so as long as you use this:

 use Closure::Explicit qw(callback);

to import the function into your local namespace, or fully-qualify it using

 Closure::Explicit::callback { ... }

then you should have no problems with future versions of this module.

However, it is highly likely that a future version will also start exporting a differently-named function with a better interface.



Checks the given coderef for potential closure issues, raising an exception if any are found and returning the coderef (or a wrapped version of it) if everything is okay.

The first parameter is the block of code to run. This is protoyped as & so you can replace the usual 'sub { ... }' with 'callback { ... }'. If you already have a coderef, you can pass that using &callback($code, ...) , but please don't.

Remaining parameters are optional - you can either pass a single array, containing a list of the names of the variables that are safe to capture:

 callback { print "$x\n" } [qw($x)];

or a list of named parameters:

For example, a method call might look like this:

 my $code = callback {
   my $self = shift;
 } weaken => [qw($self)];

although curry::weak would be a much cleaner alternative there:

 my $code = $self->curry::weak::method;

You can mix weaken and allowed:

 my $x = 1;
 my $code = callback {
 } weaken => [qw($self)], allowed => [qw($x)];


Runs checks on the given coderef. This is used internally and not exported, but if you just want to get a list of potential problems for a coderef, call this:

 my @errors = lint($code, allowed => [qw($x)]);

It's unlikely that the weaken parameter will work when calling this function directly - this may be fixed in a future version.



Tom Molesworth <>


Copyright Tom Molesworth 2012-2013. Licensed under the same terms as Perl itself.

syntax highlighting: