That is not so. First of all you misunderstood what was
going on with runrig's nitpickery. Consider the
following piece of code:
my $anon1 = outer(1);
my $anon2 = outer(2);
inner();
$anon1->(3);
$anon2->(4);
inner();
$anon1->();
$anon2->();
sub outer {
my $y = my $x = shift;
sub inner {
print "Inner thinks x is '$x'.\n";
}
return sub {
print "Anon $y thinks x is '$x'.\n";
if (@_) {
$x = shift;
print "Anon $y reset x to '$x'.\n";
}
};
}
__DATA__
Inner thinks x is '1'.
Anon 1 thinks x is '1'.
Anon 1 reset x to '3'.
Anon 2 thinks x is '2'.
Anon 2 reset x to '4'.
Inner thinks x is '3'.
Anon 1 thinks x is '3'.
Anon 2 thinks x is '4'.
If you run this you will see what is really going on.
The inner subroutine generates a closure. However there
are 2 instances of the environment available, and only one
global name. That global name therefore closes the
subroutine over the first instance of the scope
encountered. Subsequent calls to the outer function are
not bound to the inner named subroutine because they are
generating scopes that the innner one does not share.
This behaviour is a correct and logical resolution to the
ambiguities between global naming and lexical scopes. But
it tends not to do what is expected.
However you did not just misunderstand what was going on
with the issue that demerphq and runrig pointed out.
You added to that the accusation that, 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. This accusation is, your protestations of
obviousness notwithstanding, wrong. They work perfectly
well as long as the function names are scoped lexically,
just like the variables bound into the function's
environment, so there is no ambiguity about which
set of variables to bind the function to.
I think this has all been a misunderstanding on your part.
Hopefully now you see how closures work in Perl, see how
they really are the same as in other languages, understand
why what demerphq noted and then runrig followed up on
is a problem in Perl, and understand why the problem does
not have any easy solution.
UPDATE (much later): Added the output. Also I should point out that it is exactly this issue which causes Perl to issue a "Variable ____ will not stay shared" warning in this case. |