Newbie in Perl again here, trying to understand closure
in Perl.
So here\'s an example of code which I don\'t understand:
sub make_saying {
In Perl, scalar variables cannot hold subroutines directly, they can only hold references. This is very much like scalars cannot hold arrays or hashes, only arrayrefs or hashrefs.
The sub { ... }
evaluates to a coderef, so you can directly assign it to a scalar variable. If you want to assign a named function (e.g. foo
), you have to obtain the reference like \&foo
.
You can call coderefs like $code->(@args)
or &$code(@args)
.
The code
$f = \make_saying("Howdy")
evaluates make_saying("Howdy")
, and takes a reference to the returned value. So you get a reference that points to a coderef, not a coderef itself.
Therefore, it can't be called like &$f("world")
, you need to dereference one extra level: &$$f("world")
.
A closure is a function that is bound to a certain environment.
The environment consists of all currently visible variables, so a closure always remembers this scope. In the code
my $x;
sub foo {
my $y;
return sub { "$x, $y" };
}
foo
is a closure over $x
, as the outer environment consists of $x
. The inner sub is a closure over $x
and $y
.
Each time foo
is executed, we get a new $y
and therefore a new closure. Each time it is called, a different closure is returned.
When we execute make_saying("Howdy")
, the $salute
variable is set to Howdy
. The returned closure remembers this scope.
When we execute it again with make_saying("Greetings")
, the body of make_saying
is evaluated again. The $salute
is now set to Greetings
, and the inner sub closes over this variable. This variable is separate from the previous $salute
, which still exists, but isn't accessible except through the first closure.
The two greeters have closed over separate $salute
variables. When they are executed, their respective $salute
is still in scope, and they can access and modify the value.