Hi
Athanasius
But if we attempt to do this with a function template, the warning we get:
Use of uninitialized value in addition (+) at...
shows that the inner sub is actually run at the time when the outer sub is called.
I may have misunderstood this part of your post, but I interpreted it to mean that it is not possible to build a closure with a function template. That surprised me quite a bit, so I decided to try, modifying your sample code.
When I run this code:
use strict;
use warnings;
local *f1 = make_adder( 20);
printf "result f1 = %d\n", f1(10);
local *f2 = make_adder(555);
printf "result f2 = %d\n", f2(10);
sub make_adder {
my $addpiece = shift;
print "\$addpiece = $addpiece\n";
*inner = sub {
return shift() + $addpiece;
};
return *inner;
}
I get a warning, but it seems to work nonetheless (at least to print the correct values):
$ perl func_template2.pl
$addpiece = 20
result f1 = 30
$addpiece = 555
Subroutine main::inner redefined at func_template2.pl line 15.
result f2 = 565
Fair enough, the warning says that the
inner function is being redefined, which is of course not a very good idea in this context (and, as we know and as you have shown with your example, we would not have that with lexical code refs, which is a good reason to think that lexical code refs are superior to function templates for that kind of things). But, yet, the functions f1 and f2 can still print the right values, meaning that they apparently can close on these values. And I don't get any warning if I use only f1 (and not f2).
I would tend to think that it is likely to be my fault and that I probably did not understand correctly what you meant to say, but, if such is the case, I would like to ask you to explain further what you meant.