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: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to