Exercise for Chapter 7 of "Intermediate Perl"

 
 
   
   
     
     
#########################################################################
     
     
# Brief: Exercise for Chapter 7 of "Intermediate Perl"
     
     
# File: ch7_exam.pl
     
     
# Creator: thinkhy
     
     
# Date: 12/23/2012
     
     
#########################################################################
     
     
use File:: Find ;
     
     
use Time:: Local ;
     
     
use File::Spec:: Functions qw(canonpath no_upwards) ;
     
     
     
     
my $target_dow = 2 ; # Sunday is 0, Monday is 1, ...
     
     
my @starting_directories = ( "." , "e:/tmp" );
     
     
my $seconds_per_day = 24 * 60 * 60 ;
     
     
my ( $sec , $min , $hour , $day , $mon , $yr , $dow ) = localtime ;
     
     
my $start = timelocal ( 0 , 0 , 0 , $day , $mon , $yr ); # midnight today
     
     
     
     
while ( $dow != $target_dow ) {
     
     
# Back up one day
     
     
$start -= $seconds_per_day ; # hope no DST! :?)
     
     
if ( -- $dow < 0 ) {
     
     
$dow += 7 ;
     
     
}
     
     
}
     
     
     
     
my $stop = $start + $seconds_per_day ;
     
     
my ( $gather , $yield ) = gather_mtime_between ( $start , $stop );
     
     
find ( $gather , @starting_directories );
     
     
     
     
my @files = $yield -> ( );
     
     
for my $file ( @files ) {
     
     
my $mtime = ( stat $file )[ 9 ]; # mtime via slice
     
     
my $when = localtime $mtime ;
     
     
print "$when: $file\n" ;
     
     
}
     
     
     
     
sub gather_mtime_between {
     
     
my $start_time = shift ;
     
     
my $end_time = shift ;
     
     
     
     
my @files = ();
     
     
     
     
#########################################################################
     
     
# Here use canonpath, details explained as below
     
     
# canonpath:
     
     
# No physical check on the filesystem, but a logical cleanup of a path.
     
     
# no_upwards:
     
     
# Given a list of file names, strip out those that refer to a
     
     
# parent directory. (Does not strip symlinks,
     
     
# only '.', '..', and equivalents.)
     
     
# Refer to http://perldoc.perl.org/File/Spec.html
     
     
#
     
     
# Also, notice that when using stat inside the callback, the filename is $_
     
     
# but when the filename reperting to the user, the name is $File::Find::name
     
     
# because different current working directory for callback and user function
     
     
#########################################################################
     
     
sub {
     
     
my $when = ( stat $_ )[ 9 ];
     
     
push @files , canonpath ( $ File::Find:: name )
     
     
if ( $when >= $start_time and $when <= $end_time ) },
     
     
sub { @files = no_upwards ( @files );
     
     
wantarray ? @files : [ @files ] }
     
     
}
     
     
     
     
# Here is the 'official' answer for Chapter 7
     
     
sub gather_mtime_between {
     
     
my ( $begin , $end ) = @_ ;
     
     
my @files ;
     
     
     
     
my $gatherer = sub {
     
     
my $timestamp = ( stat $_ )[ 9 ];
     
     
unless ( defined $timestamp ) {
     
     
warn "Can't stat $File::Find::name: $!, skipping\n" ;
     
     
return ;
     
     
}
     
     
push @files , $ File::Find:: name
     
     
if $timestamp >= $begin and $timestamp <= $end ;
     
     
};
     
     
     
     
my $fetcher = sub { @files };
     
     
( $gatherer , $fetcher );
     
     
}
     
     
 
     
     
############################################################################
     
     
# Compared with answer, I omitted a special condition that the timestamp
     
     
# will be undef if the stat fails for some reason. That can happen, for example,
     
     
# if it finds a dangling symbolic link(the target file doesn't exist).
     
     
# In that case, the callback warns the user and returns early.
     
     
# With the code of answer, if we omit that check, we can get warnings of 
# an undefined value during the comparison with begin time and end time.
     
     
############################################################################

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值