mr.nick has asked for the wisdom of the Perl Monks concerning the following question:

So, I needed a function that would compare the timestamp of one file to a directory full of files. If the one first was newer than all the others, the function would continue; otherwise, it would return.

I tried to be clever about this and got the following:

sub chk_snapshot { my $dir=shift; return unless -f "$dir/.snapshot"; my $ft=(stat("$dir/.snapshot"))[9]; my @fts=map { (stat($_))[9] } grep -f $_,($0,glob "$dir/*"); ## return if .snapshot is older than any for my $x (@fts) { return if $x > $ft; } warn "snapshot is newer"; snarf_file("$dir/.snapshot"); }
What I wanted to do is get rid of the for my $x (@fts) construct and somehow combine it with the map statement (getting rid of the @fts variable at the same time). I had tried something like
return if map { (stat($_))[9] > $ft } grep -f $_,($0,glob "$dir/*");
But that didn't work because map returns (in this case) an array of undef's, not an empty array; so the return in that construct is always executed.

So my question is, does anyone know how to achieve the goal of gathering the filestamps AND checking them in a single line (like my non-functional return if map ...)?

TIA!

Replies are listed 'Best First'.
Re: Clever timestamp comparison
by japhy (Canon) on May 06, 2001 at 00:33 UTC
    You could just change the 'map' to 'grep' in your non-functional example. But that seems wasteful. Don't go through more files than you need.
    my $file = $0; { return if (stat $_)[9] > $ft; do { $file = glob "$dir/*" } until -f $file; redo if defined $file; }
    Try something like that. I don't think using a do ... until ..., nor a do ... redo is ugly. They exist for specific reasons. However, here's another approach:
    for (my $file = $0; defined $file; $file = glob "$dir/*") { next unless -f $file; return if (stat $_)[9] > $ft; }
    modified: or
    for (my $file = $0; ; $file = glob "$dir/*") { last unless defined $file; next unless -f $file; return if (stat $_)[9] > $ft; }


    japhy -- Perl and Regex Hacker
Re: Clever timestamp comparison
by Beatnik (Parson) on May 06, 2001 at 01:38 UTC
    Date::Calc has a nice func that does a similar thing... Delta_Days($year1,$month1,$day1, $year2,$month2,$day2);

    Greetz
    Beatnik
    ... Quidquid perl dictum sit, altum viditur.
Re: Clever timestamp comparison
by boo_radley (Parson) on May 06, 2001 at 00:35 UTC
    Why not simply put the return statement inside of the map?
    Of course, that would wind up being mapping in a void context, and some people frown upon that.