=head1 NAME
-perlfaq7 - General Perl Language Issues ($Revision: 3606 $)
+perlfaq7 - General Perl Language Issues ($Revision: 8539 $)
=head1 DESCRIPTION
Closures are documented in L<perlref>.
I<Closure> is a computer science term with a precise but
-hard-to-explain meaning. Closures are implemented in Perl as anonymous
-subroutines with lasting references to lexical variables outside their
-own scopes. These lexicals magically refer to the variables that were
-around when the subroutine was defined (deep binding).
-
-Closures make sense in any programming language where you can have the
-return value of a function be itself a function, as you can in Perl.
-Note that some languages provide anonymous functions but are not
-capable of providing proper closures: the Python language, for
+hard-to-explain meaning. Usually, closures are implemented in Perl as
+anonymous subroutines with lasting references to lexical variables
+outside their own scopes. These lexicals magically refer to the
+variables that were around when the subroutine was defined (deep
+binding).
+
+Closures are most often used in programming languages where you can
+have the return value of a function be itself a function, as you can
+in Perl. Note that some languages provide anonymous functions but are
+not capable of providing proper closures: the Python language, for
example. For more information on closures, check out any textbook on
functional programming. Scheme is a language that not only supports
but encourages closures.
-Here's a classic function-generating function:
+Here's a classic non-closure function-generating function:
sub add_function_generator {
return sub { shift() + shift() };
$add_sub = add_function_generator();
$sum = $add_sub->(4,5); # $sum is 9 now.
-The closure works as a I<function template> with some customization
-slots left out to be filled later. The anonymous subroutine returned
-by add_function_generator() isn't technically a closure because it
-refers to no lexicals outside its own scope.
+The anonymous subroutine returned by add_function_generator() isn't
+technically a closure because it refers to no lexicals outside its own
+scope. Using a closure gives you a I<function template> with some
+customization slots left out to be filled later.
Contrast this with the following make_adder() function, in which the
returned anonymous function contains a reference to a lexical variable
hypothetical timeout() function to access the lexical variable
$line back in its caller's scope.
+Another use for a closure is to make a variable I<private> to a
+named subroutine, e.g. a counter that gets initialized at creation
+time of the sub and can only be modified from within the sub.
+This is sometimes used with a BEGIN block in package files to make
+sure a variable doesn't get meddled with during the lifetime of the
+package:
+
+ BEGIN {
+ my $id = 0;
+ sub next_id { ++$id }
+ }
+
+This is discussed in more detail in L<perlsub>, see the entry on
+I<Persistent Private Variables>.
+
=head2 What is variable suicide and how can I prevent it?
This problem was fixed in perl 5.004_05, so preventing it means upgrading
my $f = 'foo';
sub T {
- while ($i++ < 3) { my $f = $f; $f .= $i; print $f, "\n" }
+ while ($i++ < 3) { my $f = $f; $f .= "bar"; print $f, "\n" }
}
T;
print "Finally $f\n";
objects. See L<perlsub/"Pass by Reference"> for this particular
question, and L<perlref> for information on references.
-See "Passing Regexes", below, for information on passing regular
-expressions.
+See "Passing Regexes", later in L<perlfaq7>, for information on
+passing regular expressions.
=over 4
sub counter { $count++ }
}
- my $start = count();
+ my $start = counter();
- .... # code that calls count();
+ .... # code that calls counter();
- my $end = count();
+ my $end = counter();
In the previous example, you created a function-private variable
because only one function remembered its reference. You could define
This is explained in more depth in the L<perlsyn>. Briefly, there's
no official case statement, because of the variety of tests possible
in Perl (numeric comparison, string comparison, glob comparison,
-regex matching, overloaded comparisons, ...).
-Larry couldn't decide how best to do this, so he left it out, even
-though it's been on the wish list since perl1.
+regex matching, overloaded comparisons, ...). Larry couldn't decide
+how best to do this, so he left it out, even though it's been on the
+wish list since perl1.
Starting from Perl 5.8 to get switch and case one can use the
Switch extension and say:
line in your perl script (the "shebang" line) does not contain the
right path to perl (or any other program capable of running scripts).
Sometimes this happens when you move the script from one machine to
-another and each machine has a different path to perl---/usr/bin/perl
+another and each machine has a different path to perl--/usr/bin/perl
versus /usr/local/bin/perl for instance. It may also indicate
that the source machine has CRLF line terminators and the
destination machine has LF only: the shell tries to find
=head1 REVISION
-Revision: $Revision: 3606 $
+Revision: $Revision: 8539 $
-Date: $Date: 2006-03-06 12:05:47 +0100 (lun, 06 mar 2006) $
+Date: $Date: 2007-01-11 00:07:14 +0100 (jeu, 11 jan 2007) $
See L<perlfaq> for source control details and availability.
=head1 AUTHOR AND COPYRIGHT
-Copyright (c) 1997-2006 Tom Christiansen, Nathan Torkington, and
+Copyright (c) 1997-2007 Tom Christiansen, Nathan Torkington, and
other authors as noted. All rights reserved.
This documentation is free; you can redistribute it and/or modify it