Although a naked block worked nicely to define the callback, having a
subroutine return that subroutine reference instead might be more
useful:
use File::Find;
sub create_find_callback_that_counts {
my $count = 0;
return sub { print ++$count, ": $File::Find::name\n" };
}
my $callback = create_find_callback_that_counts( );
print "my bin:\n";
find($callback, "bin");
print "my lib:\n";
find($callback, "lib");
This example prints consecutive numbers starting at 1 for the entries
below my bin, but then
continues the numbering when you start entries in
lib. The same $count variable
is used in both cases. However, if you invoke the
create_find_callback_that_counts( ) twice, you get
two different $count variables:
use File::Find;
sub create_find_callback_that_counts {
my $count = 0;
return sub { print ++$count, ": $File::Find::name\n" };
}
my $callback1 = create_find_callback_that_counts( );
my $callback2 = create_find_callback_that_counts( );
print "my bin:\n";
find($callback1, "bin");
print "my lib:\n";
find($callback2, "lib");
The two subroutine references are not invoked by returning their
references from the creating subroutine. The references are just data
at that point. It's not until you invoke them as a
callback or an explicit subroutine derefencing that they actually do
their duty.
What if you invoke this new subroutine more than once?
use File::Find;
sub create_find_callbacks_that_sum_the_size {
my $total_size = 0;
return(sub { $total_size += -s if -f }, sub { return $total_size });
}
## set up the subroutines
my %subs;
foreach my $dir (qw(bin lib man)) {
my ($callback, $getter) = create_find_callbacks_that_sum_the_size( );
$subs{$dir}{CALLBACK} = $callback;
$subs{$dir}{GETTER} = $getter;
}
## gather the data
for (keys %subs) {
find($subs{$_}{CALLBACK}, $_);
}
## show the data
for (sort keys %subs) {
my $sum = $subs{$_}{GETTER}->( );
print "$_ has $sum bytes\n";
}