NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.
All the Perl that's Practical to Extract and Report
Stories, comments, journals, and other submissions on use Perl; are Copyright 1998-2006, their respective owners.
Interface (Score:2, Informative)
Yeah, I thought about doing a "nice" version of File::Find myself. I wanted to tie in a few things as well - the ability to get structured data as well as lists from it, and to cache data.
I'm not sure I like the stream-y interface you've got here - powerful, but violates the KISS principle which makes File::Find such a pain in the arse to use at the moment. I'd pictured more of a hash-based interface, but I hadn't thought of options so much (but I guess they could be done either by regexps or arrays).
myRe:Interface (Score:1)
I'd like to see something like this:
my @files = find('/tmp', { maxdepth => 10, mindepth => 5, name => qr/\.*\.c$/ });(Which I btw already have working in a small example I hacked together.) I really like your idea of using arrays for alternation, but how do you decide wheter to AND or OR? (AND doesn't make much sense in your example though).
Instead of returning the files I'd also consider an 'exec' like option that took a s
Re:Interface (Score:1)
It is of course not nearly done, but if anyone feel they like the concept and want to use it please feel free to do so.
package Find;
use strict;
use vars qw($VERSION @EXPORT @EXPORT_OK %EXPORT_TAGS @ISA);
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(find);
@EXPORT_OK = qw(find);
$VERSION = '0.1';
sub find {
my $dir = shift || die "Need a directory to start at\n";
die "Not a directory\n" unless -d $dir || ref($dir) eq 'ARRAY';
my $opts = shift || {};
$opts->{print} = defined($opts->{print}) ? $opts->{print} : 1;
my $depth = 1;
my @files = ();
if (ref($dir) eq 'ARRAY') {
traverse_dir($_, $depth, $opts, \@files) for @{$dir};
} else {
traverse_dir($dir, $depth, $opts, \@files);
}
return @files;
}
sub traverse_dir {
my $dir_name = shift;
my $depth = shift;
my $opts = shift;
my $files_ref = shift;
if (defined($opts->{maxdepth}) && $opts->{maxdepth} {_ok} = 1;
if (defined($opts->{name})) {
if ($file !~
$opts->{_ok} = 0;
}
}
if (defined($opts->{mindepth})) {
if ($depth {mindepth}) {
$opts->{_ok} = 0;
}
}
if ($opts->{_ok}) {
if ($opts->{print}) {
push @{$files_ref}, $dir_name . "/" . $file;
}
if (defined($opts->{'exec'})) {
&${$opts->{exec}}($dir_name . "/" . $file);
}
}
traverse_dir($dir_name . "/" . $file, $depth + 1, $opts, $files_ref) if -d $dir_name . "/" . $file;
}
closedir(DH);
}
1;
__END__
=head1 NAME
Find - find files in filesystem
=head1 SYNOPSIS
use Find;
find('/tmp', { 'exec' => \sub { print $_[0] . "\n"; }});
=head1 OPTIONS
find('directory', {
find(['directory1','directory2'], {
It currently has the following options
=head2 print
print in this context refers to wheter or not to return an array of
the files found.
for (find('/tmp', { 'print' => 1 })) {
print $_ . "\n";
}
Would print a list of files found in the '/tmp' directory.
print is set to return a list of files by default.
=head2 exec
exec is an anonymous reference to a function to call which gets passed
as the only argument the filename matching any other conditions.
find('/tmp', { 'exec' => \sub { print $_[0] . "\n"; } });
=head2 name
name is a regular expression to which the file is matched. If the file
in question matches the file the other tests on the file are performed.
find('/tmp', { name => qr/\.c$/, 'exec' => \sub { print $_[0] . "\n";} });
=head2 maxdepth
maxdepth is the maximum number of directories to descend into.
=head2 mindepth
mindepth is the minimum number of directories where matching starts.
=end
Reply to This
Parent