use strict;
use warnings;
sub outer {
my $foo;
sub inner {
$foo;
}
inner();
}
####
>perl -c test.pl
Variable "$foo" will not stay shared at test.pl line 8.
test.pl syntax OK
##
##
use strict;
use warnings;
sub outer {
my $foo;
my $inner = sub {
$foo;
};
$inner->();
}
##
##
>perl -c test.pl
test.pl syntax OK
##
##
use strict;
use warnings;
sub outer {
my $inner = sub {
$inner->()
}
}
##
##
Global symbol "$inner" requires explicit package name at test.pl line 6.
test.pl had compilation errors.
##
##
use strict;
use warnings;
sub outer {
my $inner;
$inner = sub {
$inner->()
}
}
##
##
>perl -c test.pl
test.pl syntax OK
##
##
# ReleaseTracker.pm
# This "module" simply provides "o()", a
# func that creates a simple object whose
# sole purpose is to print "Destroyed" when
# it is freed. The inner workings are not
# relevant to this example.
use strict;
use warnings;
package ReleaseTracker;
BEGIN {
our @EXPORT_OK = qw( o );
require Exporter;
*import = \&Exporter::import;
}
sub new { return bless(\(my $o), $_[0]); }
sub DESTROY { print("Destroyed\n"); }
sub o { ReleaseTracker->new(); }
1;
##
##
use strict;
use warnings;
use ReleaseTracker qw( o );
sub outer {
# Variables that are read by each recursive instance.
my $var = shift @_;
my $helper;
$helper = sub {
no warnings 'void';
"do something with $var and @_";
$helper->(@_);
};
#$helper->(@_);
}
outer( o() );
END { print("On program exit:\n"); }
##
##
>perl test.pl
On program exit:
Destroyed <--- BAD!
##
##
use strict;
use warnings;
use ReleaseTracker qw( o );
sub outer {
# Variables that are read by each recursive instance.
my $var = shift @_;
local *helper = sub {
no warnings 'void';
"do something with $var and @_";
helper(@_);
};
#helper(@_);
}
outer( o() );
END { print("On program exit:\n"); }
##
##
>perl test.pl
Destroyed
On program exit:
<-- good
##
##
sub outer {
...
local *helper = sub {
...
helper(...);
...
};
helper(@_);
}
##
##
sub outer {
...
Y( sub {
my $helper = shift @_;
sub {
...
$helper->(...);
...
}
} )->(@_);
}
##
##
sub outer {
...
my $helper;
$helper = sub {
...
$helper->(...);
...
};
weaken($helper);
$helper->(@_);
}