Blob


1 #!/usr/bin/perl
3 # The Professor modified some files on Monday afternoon and now he's
4 # forgotten which ones they were. This happens all the time. He wants you
5 # to make a subroutine called gather_mtime_between, which, given a starting
6 # and ending timestamp, returns a pair of coderefs. The first one will be
7 # used with File::Find to gather the names of only the items that were
8 # modified between those two times; the second one you can use to get the
9 # list of items found.
11 # Here's some code to try; it should list only items that were last
12 # modified on the most recent Monday, although you could easily change it
13 # to work with a different day.
14 #
15 # Hint: We can find a file's timestamp (mtime) with code such as:
16 #
17 # $ my timestamp = (stat $file_name)[9];
18 #
19 # Because it's a slice, remember that those parentheses are mandatory.
20 # Don't forget that the working directory inside the callback isn't
21 # necessarily the starting directory from which we called find:
22 #
23 # Note the comment about DST. In many parts of the world, on the days when
24 # daylight saving time or summer time kicks in and out, the civil day is no
25 # longer 86,400 seconds long. The program glosses over this issue, but a
26 # more careful coder might take it into consideration appropriately.
28 use v5.24;
29 use warnings;
30 use strict;
31 use utf8;
32 use local::lib;
33 use File::Find;
34 use Time::Local;
36 sub gather_mtime_between {
37 my($start, $end) = @_;
38 my @files;
39 return (
40 sub {
41 my $mtime = (stat $_)[9];
42 if ($start < $mtime && $mtime < $end) {
43 push @files, $File::Find::name;
44 }
45 },
46 sub { wantarray? @files : [@files]; });
47 }
49 my $target_dow = 1; # Sunday is 0, Monday is 1, ...
50 my @starting_directories = (".");
52 my $seconds_per_day = 24 * 60 * 60;
53 my($sec, $min, $hour, $day, $mon, $yr, $dow) = localtime;
54 my $start = timelocal(0, 0, 0, $day, $mon, $yr); # midnight today
55 while ($dow != $target_dow) {
56 # Back up one day
57 $start -= $seconds_per_day; # hope no DST! :-)
58 if (--$dow < 0) {
59 $dow += 7;
60 }
61 }
62 my $stop = $start + $seconds_per_day;
64 my($gather, $yield) = gather_mtime_between($start, $stop);
65 find($gather, @starting_directories);
66 my @files = $yield->( );
68 for my $file (@files) {
69 my $mtime = (stat $file)[9]; # mtime via slice
70 my $when = localtime $mtime;
71 print "$when: $file\n";
72 }