Closures are anonymous subroutines which reference lexical
variables of a surrounding block and this way retain their values.
Here is an example from the textbooks:
sub genanon
{
my ($string) = @_;
return sub {print "$string\n"};
}
my $f1 = genanon( "Guten Tag");
my $f2 = genanon( "Hallo");
&$f1(); # prints 'Guten Tag'
&$f2(); # prints 'Hallo'
The variable $string is created, each time genanon is invoked.
Normally lexical variables are deallocated when the surrounding
function exits. But genanon creates a function that uses $string.
This has the effect that the reference count to the value of
$string does not reach zero when genanon returns.
Hence $f1 and $f2 refer to subroutines that have
some private piece of data.
Let's look at a more realistic example. Closures are
best put into action as call-back routines for widgets.
In the following example a menu button is created which allows the user to set a
variable named $var. Each of
the menu items select a specific value.
#!/usr/bin/perl -w
use strict;
use Tk 800.000;
use vars qw($var);
$var = 1;
my $w_top = Tk::MainWindow->new;
my $b = $w_top->Menubutton( -relief => 'raised',
-text => "Button: $var")->pack();
foreach my $i qw( 1 2 5 10 20)
{
$b->command( -label => "$i",
-command => sub {
$var = $i;
$b->configure( -text => "Button: $var")});
}
#
# exit button
#
$w_top->Button( -relief => 'raised',
-text => "exit",
-command => sub { $w_top->destroy();})->pack();
MainLoop;
Notice that $i is a lexical variable to the foreach loop block.
Thus the anonymous functions which are assigned to the -command
parameter contain private values of $i.
Closures are a bit confusing. To clarify things it may be instructive
to modify the code in a way that it fails: replace
'use vars qw($var)' by 'use vars qw($var $i)' and
'my $i' by '$i' . Insert a '$i = 1234;' line
before the loop. $i is turned into
a global variable. All actions that are invoked by the button
set $var to 1234.