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 ;-)
| [reply] [d/l] |
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:
| [reply] |
|
| [reply] |
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? | [reply] |
|
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? | [reply] [d/l] |
|
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). | [reply] [d/l] |
|
|
|
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
| [reply] [d/l] |
Re (tilly) 1: Why are closures cool?
by tilly (Archbishop) on Jan 13, 2002 at 03:22 UTC
|
| [reply] |
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. | [reply] |