It's easy to get a Perl subroutine to "return" another subroutine. Just create and return a code ref a reference to another subroutine (see Item 30). There are two mechanisms for creating code refs: the reference operator \ and the anonymous subroutine constructor sub { } :
The simplest and (I think) most aesthetically pleasing way to call a subroutine from a code ref is via the dereferencing arrow -> : [9]
Of course, the example above doesn't do anything particularly useful. It shows how to return and call code refs, sure, but it's just a useless extra level of indirection. This isn't a productive way to code unless we can return subroutines whose functionality is computed at run time. Creating closuresAn interesting thing happens when an anonymous subroutine uses a my variable defined in an enclosing scope. Each time the enclosing scope is entered, the subroutine gets a different copy of the my variable. An anonymous subroutine that refers to a my variable from an enclosing scope is called a closure . Or, stated another way, a closure is an anonymous subroutine that has access to private variables of its own that are otherwise inaccessible. Closures are a tricky subject, best approached with some examples. First, let's look at a very simple use of closures:
The first loop generates three code refs, each of which is a reference to a separate copy of sub { $time } . Each of those copies has its own copy of $time , created when my $time was encountered at the top of the loop. Each copy of $time can be accessed by the copy of sub { $time } that it is bound to, even (or especially ) later in the execution of the program when the my variable has gone out of scope. Generally, subroutines are used to generate closures:
Each time make_counter is called, it returns a reference to a new copy of sub { $i++ } , with its own private copy of $i . When one of those copies is called later, it still has access to its copy of $i even though the call comes from outside the scope that originally defined the my variable. Perl closures have uses that parallel those of object-oriented constructs (see Item 49). Whereas object-oriented programming is all about data with associated functions, closures are all about functions with associated data. Two or more closures can even share a common set of variables, allowing a programming style that starts to look very object-oriented indeed: Closures can share a set of variables.
While the subroutines generated in the next example aren't, strictly speaking, closures, the following illustrates the use of eval to create code refs whose bodies are read from a file:
Creating subroutines for pattern matchingIt's not uncommon to need to perform one or more pattern matches that are specified at run time. For example, you might be writing a Perl program to sort through your mail or news. Such a program would likely read in a "kill file" of patterns to match against the headers. You can specify matches at run time by interpolating variables into regular expressions, but such regular expressions will be repeatedly compiled (see Item 22), at a considerable cost in speed. The /o option provides a means for compiling a pattern match containing interpolated variables only once. However, if you have several such matches to deal with, you are faced with a bit of a sticky wicket. Using closures in combination with eval allows you to generate subroutines that have particular regular expressions "locked in" with the same flexibility (and efficiency!) as if the expressions were specified at compile time. Here's how it's done: Create pattern matching subroutines with closures and string eval .
The key to this construct is the use of string eval in make_grep . Using /o inside string eval still means "compile once," but "once" now means once per eval , not once per program execution. It almost seems like cheating. If you want plain old pattern matching instead of grep -ing, that's easy enough:
|