Actually, I've been thinking about this and I think my preferred interface might be an object that lets you iterate in several directions so you can pick depth-first or bredth-first and decide to prune your search in what I consider more natural ways:
# The simple case like File::Find / File::Iterator
my $iter= File::Whatever->new( $root );
while( $iter->NextItem() ) {
doSomething( $iter->GetFileName() );
}
# Recurse yourself:
my $iter= File::Whatever->new( $root );
MyFunc( $iter );
sub MyFunc {
my $iter= shift(@_);
# Uncomment next line for depth-first search:
MyFunc( $iter ) while $iter->PushPath();
while( my $file= $iter->NextFile() ) {
doSomething( $file );
}
# Uncomment next line for bredth-first search:
#MyFunc( $iter ) while $iter->PushPath();
$iter->PopPath();
}
# Example of pruning your search:
my $iter= File::Whatever->new( $root );
MyFunc( $iter );
sub MyFunc {
my $iter= shift(@_);
while( my $file= $iter->NextFile() ) {
doSomething( $file );
}
while( my $sub= $iter->PushPath() ) {
if( $sub =~ /debug/i ) {
$iter->PopPath();
} else {
MyFunc( $iter );
}
}
$iter->PopPath();
}
# Bredth-first search w/o recursion:
my $iter= File::Whatever->new( $root );
do {
while( my $file= $iter->NextFile() ) {
doSomething( $file );
}
} while( $iter->NextPath() );
# Bredth-first search w/ pruning w/o recursion:
my $iter= File::Whatever->new( $root );
do {
while( my $file= $iter->NextFile() ) {
doSomething( $file );
}
while( $iter->NextPath() =~ /debug/i ) {
$iter->PopPath();
}
} while( ! $iter->Finished() );
# Depth-first search w/o recursion:
my $iter= File::Whatever->new( $root );
do {
0 while $iter->PushPath();
while( my $file= $iter->NextFile() ) {
doSomething( $file );
}
} while( $iter->PopPath() );
# Depth-first search w/ pruning w/o recursion:
my $iter= File::Whatever->new( $root );
do {
while( my $sub= $iter->PushPath() ) {
$iter->PopPath() if $sub =~ /debug/i;
}
while( my $file= $iter->NextFile() ) {
doSomething( $file );
}
} while( $iter->PopPath() );
# The opposite of pruning:
# Only do things to files in directories named "debug"
my $iter= File::Whatever->new( $root );
do {
if( 'debug' eq $iter->GetDirName() ) {
while( my $file= $iter->NextFile() ) {
doSomething( $file );
}
}
} while( $iter->NextPath() );
But I need to think about that a lot more before I'm sure that such makes sense or if I can make it better. (:
- tye |