I do not fully understand the solution to the problem, p77-78 & 237.
First, the declaration of the array my @files in the subroutine
gather_mtime_between will be read every time find($gather,
$starting_directories) calls the subroutine. I take it the repeated
declarations have no effect and since this is a named subroutine the
array retains the list from the most previous call.
Second, the statement my $fetcher = sub { @files }; creates an anonymous
subroutine with the array @files as a return value.
Third, each time the subroutine gather_mtime_between is called by
find($gather, $starting_directories) it is passed the values $_ and
File::Find::name for the currectly found file. When the finds are
completed the subroutine will be called once more by reference yield.
On this last call $_ will be undefined so the internal anonymous
subroutine will return (but no warning message?), the last statment in
the subroutine is fetcher so the return value of the subroutine is
@files.
Fourth, the statement in main body my @files = yield->( ): is the last
call to the subroutine by the reference yield. As noted in the
proceeding paragraph the return value is @files so the newly defined
gobal variable @files receives this value.
If all this is obvious as is stated on page 228, please pardon me for
taking up any readers' time but I would appreciate any confirmation that
I have thought it through correctly. If I have it wrong I do need help.
Just in case anyone takes the time to read all this but is not familiar
with the problem here is the complete working solution:
#!/usr/bin/perl -w
use strict;
use Time::Local;
use File::Find;
my @starting_directory = qw(/data/perl/Intermediate);
my $total_size = 0;
my $file_count = 0;
my $target_dow = 0;
my $Seconds_per_Day = 60 * 60 * 24;
my ($sec, $min, $hour, $day, $month, $year, $dow) = localtime;
my $start = timelocal(0, 0, 0, $day, $month, $year);
while ($dow != $target_dow) {
$start -= $Seconds_per_Day;
if (--$dow < 0) {$dow = 7};
}
my $stop = $start + $Seconds_per_Day;
sub gather_mtime_between {
my ($begin, $end) = @_;
my @files;
my $gatherer = sub {
my $timestamp = (stat $_)[9];
unless (defined $timestamp) {
warn "Cannot find $File::Find::name: $!, skipping\n";
return;
}
push @files, $File::Find::name if
$begin <= $timestamp && $timestamp <= $end;
};
my $fetcher = sub { @files };
($gatherer, $fetcher);
};
my($gather, $yield) = gather_mtime_between($start, $stop);
find ($gather, @starting_directory);
my @files = $yield->( );
foreach my $file (@files) {
my $mtime = (stat $file)[9];
my $when = localtime ($mtime);
print "$when $file\n";
}
--
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
http://learn.perl.org/