Skip to content

Instantly share code, notes, and snippets.

@manchicken
Last active December 22, 2015 02:08
Show Gist options
  • Save manchicken/6401045 to your computer and use it in GitHub Desktop.
Save manchicken/6401045 to your computer and use it in GitHub Desktop.
From my Perl closures blog post
#!/usr/bin/env perl
use 5.010; # Perl 5.10 minimum!
use strict;use warnings;
# This is just to demonstrate a simple closure
sub make_closure {
my @inputs = @_;
return sub { join ',', @inputs, @_; };
}
my $_foo = make_closure(1,2,3,4);
say $_foo->('X');
# Here is a package which will help us detect when an instance is being
# destroyed and reaped by the garbage collector.
{
package DestroyDetector;
sub new {
my ($pkg, $val) = @_;
my $self = {value=>$val};
return bless $self, $pkg;
}
sub value {
my ($self) = @_;
return $self->{value};
}
sub announce {
my ($self, $msg) = @_;
$msg //= q{};
say "Announcing DestroyDetector \"$msg\" value: ".$self->value;
}
sub DESTROY {
my ($self) = @_;
say "Destroying DestroyDetector value: ".$self->value;
return;
}
};
# Let's prove that DestroyDetector announces when undef'ed.
my $foo1 = DestroyDetector->new('foo1');
$foo1->announce("about to undef foo1");
undef($foo1);
# Now, let's define a function which returns a closure...
sub closure_one {
my ($value) = @_;
my $detector = DestroyDetector->new($value);
$detector->announce("Pre-closure definition...");
return sub {
my ($msg) = @_;
$detector->announce($msg);
};
}
# Now, let's get a copy of our closure...
my $closure1 = closure_one('closure1');
$closure1->('calling from the closure!');
$closure1->('About to undef() the closure...');
# Now let's destroy the closure and see if it destroys the $detector instance.
undef($closure1);
say 'You should have just seen the DestroyDetector destroy "closure1".';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment