develooper Front page | perl.beginners | Postings from October 2009

Re: About internal working of File::Find

Thread Previous | Thread Next
From:
Jim Gibson
Date:
October 28, 2009 15:36
Subject:
Re: About internal working of File::Find
Message ID:
C70E155B.83E7%JimSGibson@gmail.com
On 10/28/09 Wed  Oct 28, 2009  3:18 PM, "Harry Putnam" <reader@newsguy.com>
scribbled:

> Jim Gibson <jimsgibson@gmail.com> writes:
> 
>> If you want to process files in a certain order, then save the files in an
>> array. When find is finished, sort that array and process the files in any
>> order. For example, if you want to process files in chronological order, in
>> the wanted routine save the file path and age as an array entry (untested):
>> 
>>     my @files;
>>     my $dir = '/some/directory/path';
>> 
>>     find( sub{ 
>>         my $age = -M $File::Find::name;
>>         push( @files, [ $File::Find::name, $age ] );
>>         }, $dir);
>> 
>>     for my $entry ( sort { $a->[1] <=> $b[1] } @files ) {
>>         my($file,$age) = @$entry;
>>         # process file
>>     }
>> 
>> (reverse $a and $b if you want the reverse order).
> 
> I see the final result but am slightly mystified by some of the
> notation.  First off the formulation of the find() function.
> 
> I've seen it before but don't really understand it.
> 
> Seems like the guts of find() are missing, but I know they are not.
> 
> I guess it could be expressed:
> 
>   find( sub{..results of this sub routine},$dir);

Yes, that is correct. The line

    find( sub { ... ], $dir);

that contains the definition of an anonymous subroutine is equivalent to

    sub wanted { ... };
    find( \&wanted, $dir );

which uses a named subroutine. Surprisingly, the documentation for
File::Find does not mention this use of anonymous subroutine references.

> 
> Like you might do with `find($var1,$var2);'
> But there you would expect to see `find()' have some lines of
> processing to the two elems of @_ passed in.

The find() function of File::Find expects two or more arguments. The first
argument must be a subroutine reference. This subroutine is called by find()
for each directory and file found. The second and any subsequent arguments
are directories to search.

> 
> What are the brackets ([]) doing here:
>   push( @files, [ $File::Find::name, $age ] );

The brackets create a reference to an anonymous array with the specified
context. The references is then pushed onto the @files array.

> 
> and what is this creature:
>    my($file,$age) = @$entry;

This line dereferences the reference to the anonymous array saved in each
element of @files and assigns the contents of each anonymous array to the
scalar variables $file and $age.

See 'perldoc perllol' for more details on constructing and accessing nested
data structures in Perl.




Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About