package Dir::Iterate;
=head1 NAME
Dir::Iterate - map/grep-style directory traversal
=head1 SYNOPSIS
use Dir::Iterate;
my @config_dirs = grepdir { -d } '/etc';
my @filenames = mapdir { (split '/')[-1] } $ENV{HOME}, '/usr';
=head1 DESCRIPTION
Dir::Iterate implements equivalents to the built-in C<map> and C<grep> functions
which traverse directories instead of arrays. The block will be called for
each file and directory below the given list of directories. It acts as a
more usable layer on top of File::Find.
=head2 Functions
=over 4
=cut
use strict;
use warnings;
use Exporter;
use base 'Exporter';
our $VERSION = 0.01;
our @EXPORT = qw(grepdir mapdir);
use File::Find ();
use File::Spec;
=item mapdir { ... } $path1[, $path2...]
The block is called for each file, folder, or other filesystem entity under the
given path(s). The full path to the object is in $_. The return value or
values of the block are collected together and returned in a list.
=cut
sub mapdir(&@) {
my($closure, @paths) = @_;
my @results;
File::Find::find(
{
wanted => sub {
local $_ = $File::Find::fullname;
push @results, $closure->();
},
no_chdir => 1,
follow => 1
},
map { File::Spec->rel2abs($_) } @paths
);
return @results;
}
=item grepdir { ... } $path1[, $path2...]
The block is called for each file, folder, or other filesystem entity under the
given path(s). The full path to the object is in $_. If the return value of
the block is true, the full path will be in the list returned by the method.
=cut
sub grepdir(&@) {
my $predicate = shift;
unshift @_, sub { $predicate->() ? $_ : () };
goto &mapdir;
}
=back 4
=head1 EXPORTS
C<mapdir> and C<grepdir> by default.
=head1 AUTHOR
Brent Royal-Gordon <brentdax@cpan.org>, for the University of Kent.
=head1 LICENSE
This library is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.
=cut
1;