Last active
December 22, 2015 02:08
-
-
Save manchicken/6401045 to your computer and use it in GitHub Desktop.
From my Perl closures blog post
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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