in reply to Why are closures cool?

Just a thought, but closure sort of has a special meaning in perl5. While in most cases a closure has the convential "subroutine which runs in the context it was declared" meaning, ive found perlers often use it also in the sense of "Coderef to an anonymous subroutine". This probably comes from the fact that the closure mechanism in perl is partially broken, in that the common meaning can only apply to an anonymous subroutine, not an explicitly named subroutine, attempting to do so will result in "not shared" warnings. Also note that there are subtle bugs (thankfully rarely encountered) even when anonymous subs are used. (See Funkyness with closures... for an example)

There are already good examples of what you can do with closures posted so I wont give an example (aside from the others check out perltoot,perltootc for some ideas), but if you arent already familiar with the idea of anonymous subroutines/function pointers/coderefs then they are also well worth becoming aquainted with (think dispatch mechanisms and dynamic iterators).

BTW, id say a lot of perlers would include closures on their "funky things I like perl because of" list, right alongside regexes,map and grep. Have fun.

Yves / DeMerphq
--
When to use Prototypes?

Replies are listed 'Best First'.
Re^2: Why are closures cool?
by Aristotle (Chancellor) on Jan 12, 2002 at 18:57 UTC
    Are you sure?
    screamer@home:~$ cat test.pl use warnings; use strict; { my $i = 0; sub test { print ++$i, @_ } } test "\n" for 1..10; screamer@home:~$ perl -c test.pl test.pl syntax OK screamer@home:~$ perl -v This is perl, v5.6.0 built for i386-linux ...
    Doesn't look broken to me. (It executes with no warnings too, in case anyone's wondering.)

    Am I missing something?
      Doesn't look broken to me... Am I missing something?

      The 'brokenness' comes when you have a named sub inside another subroutine. If you try this:

      use strict; use warnings; sub function { my $i = 0; sub test { print ++$i,"\n"; } test(); test(); }
      You'll get a "variable will not stay shared" warning, and will not get the results you expect. This happens alot with Apache::Registry novices because people will write subroutines with global (i.e. my variables at the outermost scope) variables, and Apache::Registry wraps the entire script into a subroutine of its own, so you end up with a situation like the above (the answer being to not use globals, or put the subroutines and their globals into a package of their own).
        Oh. Well named subroutines always go into the "package scope" (is there a proper term for this?), so that code corresponds to
        use strict; use warnings; sub test { print ++$i,"\n"; } sub function { my $i = 0; test(); test(); }
        regardless of what you meant it to.

        And to be honest, I can live with that. I don't see much of a point to using named subsubroutines - unless you want to pass it around as a reference, in which case you didn't do anything less than you would have had to with an anonymous sub. Right? Of course it is correct to point out that Perl's closures are not exactly equivalent to what is commonly referred to as a closure. (Though I think whether that makes them incomplete is debatable.)