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

mr.dunstan has asked for the wisdom of the Perl Monks concerning the following question:

I humbly ask: why are closures cool or ... what do I need to know so I can understand the coolness / usefulness / whatever of closures? I feel like I've been reading all kinds of information about closures and why they're great, but I just - don't - get it! :)

-mr.dunstan

Replies are listed 'Best First'.
Re: Why are closures cool?
by seattlejohn (Deacon) on Jan 12, 2002 at 06:20 UTC
    One of the potentially useful things you can do with closures is generate subroutines dynamically based on a template. To use a rather trivial example:
    sub multiply_by { my $multiplier = $_[0]; return sub { return $_[0] * $multiplier; } } my $times2 = multiply_by(2); my $times10 = multiply_by(10); print &$times2(4), "\n"; print &$times2(6), "\n"; print &$times10(4) ,"\n"; # Results: # 8 # 12 # 40

    Used in this way, closures essentially let you create custom subs that "freeze in" the behavior of params that were passed during their creation. I find this useful occasionally if I need to define arrays of related but not identical behaviors to apply to elements in a data set, for example.

    You can also use closures to enforce strict data encapsulation, since they allow you to create variables that simply don't exist to the outside world.

    Damian Conway's excellent book Object Oriented Perl has some good examples of real reasons you might want to use closures in Perl. He certainly explains it better than this off-the-cuff response does ;-)

Re: Why are closures cool?
by screamingeagle (Curate) on Jan 12, 2002 at 06:20 UTC
    This article is a tutorial on closures in Perl. Hope it helps:
      Egads, they've always screwed up html versions of my articles --- I just threw my original plaintext version (of both parts) up here. Should be easier on all aesthetic fronts.

      Update: In fact, this was the kick in the pants I needed to do fix up my version of the archive (which was previously done with MHonArc but had holes due to lost email) --- the new text archive is: here with articles grouped by month.

Re: Why are closures cool?
by demerphq (Chancellor) on Jan 12, 2002 at 13:40 UTC
    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?

      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).
Re: Why are closures cool?
by Aighearach (Initiate) on Jan 13, 2002 at 03:01 UTC
    Closures are really cool in callback models.
    Here is an example:
    if ( $cool_stuff ) { my $foo = 0; my $bar = 42; $my_gui_object->add_callback( "<Neato_Event>", sub { my ($event, $argument) = ( @_ + ); if ( $argument == $bar ) { $foo++; return 1; } return 0; }, ); $my_gui_object->add_callback( "<WayCool_Event>", sub { my ($event, $argument) = ( @_ + ); if ( $argument == $bar ) { $foo--; return 1; } return 0; }, ); }

    now $foo is out of scope, safe and snug in it's closures. And those closures are going to be run in an unknown namespace. The only other way to get this behavior would be with... globals of some kind. bleh. :)


    --
    Snazzy tagline here
Re (tilly) 1: Why are closures cool?
by tilly (Archbishop) on Jan 13, 2002 at 03:22 UTC
Re: Why are closures cool?
by Stegalex (Chaplain) on Jan 12, 2002 at 19:39 UTC
    FYI, The topic is discussed at length in Damian Conway's book "Object Oriented Perl". While I agree with you and others that they may be cool, I don't use them. Few of the people who maintain my code would understand them. I like chicken.