OK... I bothered to finish it. Or at least get it to a working state (I don't really like just grepping out the "." and ".." directories... it feels so non-portable (even though I know it's cool on windows and *nix)).
package r;
use strict;
tie @ARGV, 'r::Tie::RecursiveARGVArray', @ARGV;
sub import { }
package r::Tie::RecursiveARGVArray;
use Tie::Array;
use base 'Tie::Array';
use File::Spec;
sub TIEARRAY {
my ($classname,@init) = @_;
bless [@init], $classname;
}
sub FETCH {
my ($self, $index) = @_;
$self->_ReplaceDirs($index,$index);
$self->[$index];
}
sub FETCHSIZE {
my ($self) = @_;
scalar @$self;
}
sub STORE {
my ($self, $index, $value) = @_;
$self->[$index] = $value;
}
sub STORESIZE {
my ($self, $count) = @_;
$#$self = $count - 1;
}
sub SPLICE {
my ($self,$offset,$length,@list) = @_;
$self->_ReplaceDirs($offset,$offset+$length-1);
splice(@$self,$offset,$length,@list);
}
sub POP {
my ($self,$item) = @_;
$self->_ReplaceDirs(-1,-1);
pop(@$self);
}
sub _ReplaceDirs {
my ($self, $fromindex, $toindex) = @_;
# as long as the index range contains directories, substitute
+the directory contents
my $recursionguard = 0;
while (my @indices = grep { -d $self->[$_] } ($fromindex..$toi
+ndex) and $recursionguard++ < 10000) {
my $index = $indices[0];
opendir DIR, $self->[$index] or do {
warn "Cannot traverse directory $self->[$index
+]: $!\n";
splice(@$self, $index, 1, ()); # remove the ba
+d-apple
next;
};
my @contents = readdir DIR or do {
warn "Cannot read directory $self->[$index]: $
+!\n";
splice(@$self, $index, 1, ()); # remove the ba
+d-apple
closedir DIR or warn "Cannot close directory $
+self->[$index] (weird): $!\n";
next;
};
closedir DIR or warn "Cannot close directory $self->[$
+index] (weird): $!\n";
# if there is any portable way to do this... I'd like
+to hear it!
@contents = grep !/^\.{1,2}$/, @contents;
# convert directory contents to paths by prepending th
+e directory.
# even be super nice about using catfile or catdir, ap
+propriately
@contents = map {
my $asfile = File::Spec->catfile( $self->[$ind
+ex], $_ );
-f $asfile ? $asfile : File::Spec->catdir( $se
+lf->[$index], $_ );
} @contents;
# replace directory with its contents
splice(@$self, $index, 1, @contents);
}
}
1;
complete with example use:
[me@host]$ cat `find d* -type f` | wc -l
58040
[me@host]$ perl -mr -lne '$x++; END{print $x}' d*
58040
[me@host]$
I guess now I should pod this up and make it my first contribution to cpan :-D
------------
:Wq
Not an editor command: Wq