http://www.perlmonks.org?node_id=494466

reasonablekeith has asked for the wisdom of the Perl Monks concerning the following question:

Okay, I've been programming in Perl for long enough now, and I really feel I ought to understand closures. So I read through the relevant section of Programming Perl, and check out the the first few google hits, which includes the very useful article Achieving Closure, and I'm sort of there with my understanding, but not quite...

A nice and succinct example of a closure I read through is as follows.

sub count_maker { my $count = shift; return sub {$count++} } my $a_counter1 = count_maker(0); my $a_counter2 = count_maker(4); print $a_counter1->() . "\n"; print $a_counter2->() . "\n"; print $a_counter2->() . "\n"; print $a_counter1->() . "\n"; __OUTOUT__ 0 4 5 1
Pretty cool. I can see that, at the time and scope of the print statement, $count is not defined. I can also accept that the locally scoped variables (relative to the sub ref) are "packaged up" uniquely for each sub ref, but what I really don't understand what it is that triggers this behaviour. Programming Perl has the following to say about Closures

Closure is a notion out of the Lisp world that says if you define an anonymous function in a particular lexical context at a particular moment, it pretends to run in that context even when it's called outside of the context.

Okay, so it's the fact that I'm calling an anonymous sub is it? $count was at the same scope as the sub definition, and therefore gets bundled-up? I can see that, so I had a further play, and came up with this...

for (0..9) { my $count = 3; # just to prove a point print counter(); } do { my $count; sub counter {$count++} } __OUTPUT__ 0123456789
I'm almost certain (*) this constitutes a closure, but it doesn't have any anonymous subroutines anywhere. So what is it about this code that tells perl to keep a copy of $count and not just print 10 zeros?

Talking to the bear, as it were, it has just occured to me that the "do" might be the anonymous function in this example, but I'm still not sure what's _actually_ going on here. I hate using something I don't fully understand, so I'd be very grateful if anyone can nudge my understanding the right direction.

Many Thanks, Rob

* but not actually certain, this may be why I'm having problems :p

---
my name's not Keith, and I'm not reasonable.