note
tobyink
<p>A closure is a subroutine that makes use of a lexical variable defined outside the subroutine. For example:</p>
<c>
use v5.14;
my $foo = 40;
sub foo {
return(2 + $foo);
}
</c>
<p>The <c>foo()</c> sub is said to be a "closure", and the <c>$foo</c> variable has be "closed over".</p>
<p>When most people talk about closures though, they are usually referring to anonymous functions rather than named ones like above. Something like:</p>
<c>
use v5.14;
sub get_counter {
my ($count) = @_;
my $closure = sub { $count++ };
return $closure;
}
my $counter = get_counter(40);
my $other = get_counter(99);
say $counter->();
say $other->();
say $counter->();
say $other->();
say $counter->();
</c>
<p>In fact, people often use the word "closures" to refer to anonymous functions <em>even if the function doesn't close over any variables</em>!</p>
<p>This is probably due to the fact that in most programming languages (including Perl) there's no syntactic difference between defining an anonymous sub that closes over a variable verses one that does not. They are implemented subtly differently internally though as can be seen by this example:</p>
<c>
use v5.14;
use Scalar::Util qw/refaddr/;
my @closures;
my @nonclosures;
for my $i (qw/ a b c /) {
push @closures, sub { $i };
push @nonclosures, sub { 42 };
}
say join "|" => map refaddr($_), @closures;
say join "|" => map refaddr($_), @nonclosures;
</c>
<p>You'll notice that the three non-closure coderefs share a reference address. This is an optimization that Perl does. (I have at least twice had to work around this optimization by defining a dummy variable and closing over it. But then again, I do a lot of weird stuff in Perl. Most people probably never need to care about this difference.)</p>
<p>Anyway, coming back to [mod://Data::Form::Validator] - it does accept coderefs as arguments in some places. Whether those coderefs are technically closures (i.e. they close over external variables), it probably doesn't care.</p>
<div class="pmsig"><div class="pmsig-757127">
<small><a href="http://toby.ink/">toby döt ink</a></small>
</div></div>
1104143
1104143