Closures
Earlier we talked about creating anonymous subroutines with a
nameless sub {}. You can think of
those subroutines as defined at runtime, which means that they have
a time of generation as well as a location of definition. Some
variables might be in scope when the subroutine is created, and
different variables might be in scope when the subroutine is
called.
Forgetting about subroutines for a moment, consider a reference that refers to a lexical variable:
{
my $critter = "camel";
$critterref = \$critter;
}The value of $$critterref
will remain “camel” even though
$critter disappears after the
closing curly brace. But $critterref could just as well have
referred to a subroutine that refers to $critter:
{
my $critter = "camel";
$critterref = sub { return $critter };
}This is a closure, which is a notion out of the functional programming world of LISP and Scheme.[127] It means that when you define an anonymous function in a particular lexical scope at a particular moment, it pretends to run in that scope even when later called from outside that scope. (A purist would say it doesn’t have to pretend—it actually does run in that scope.)
In other words, you are guaranteed to get the same copy of a lexical variable each time, even if other instances of that lexical variable have been created before or since for other instances of that closure. This gives you a way to set values used in a subroutine when you define it, not just when you call it.
You can also think of closures as a way ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access