Description: |
OOFileFind is a simple-minded wrapper around the venerable File::Find::find(), which lets you pass data into and out of the wanted() function, via OOFileFind's blessed $self. |
#!/usr/bin/perl
use strict;
use File::Find;
use File::Slurp;
package OOFileFind;
sub new {
my ( $class, $dirs ) = @_;
my $self = {
dirs => $dirs || []
};
$self->{files} = {};
bless $self, $class;
return $self;
}
sub find {
my $self = shift;
for my $dir ( @{ $self->{dirs} } ) {
File::Find::find( sub { $self->_wantedexample() }, $dir );
}
}
sub _wantedexample {
my $self = shift;
return unless /\.pl$/;
my $file = $File::Find::name;
my @lines = File::Slurp::read_file $file;
for (@lines) {
if ( my ($module) = /^\s*use\s([\w:]+)/ ) {
push @{$self->{modules}{$module}}, $file;
push @{$self->{files}{$file}}, $module;
}
}
}
package main;
my $scanner = OOFileFind->new( [ '.' ] );
$scanner->find();
printf STDERR "seen %d files :\n", scalar keys %{$scanner->{files}};
foreach my $file (sort keys %{$scanner->{files}}) {
printf STDERR " $file uses: %s\n", join ' ', @{$scanner->
+{files}{$file}};
}
printf STDERR "seen %d modules :\n", scalar keys %{$scanner->{modules}
+};
foreach my $module (sort keys %{$scanner->{modules}}) {
printf STDERR " $module used in: %s\n", join ' ', @{$scan
+ner->{modules}{$module}};
}
=head1 NAME
OOFileFind
=head1 SYNOPSIS
use OOFileFind;
my $scanner = OOFileFind->new( [ '.' ] );
$scanner->find();
# now use data collected by the $scanner
=head1 DESCRIPTION
B<mirod> of PerlMonks wrote this about using File::Find::find() :
I<My main gripe is that the wanted function, which is called for each
+file found,
does not accept arguments. So if I really need arguments,
which happens quite often, then I have to use good ole globals.
This is definitely _not_ what I'd call good coding practice.
Plus how do I put this code in a module?>
Good questions. OOFileFind module demonstrates a simple code pattern t
+hat satisfies
above requirements.
So, if I (or you) need to scan files in a set of directories and extra
+ct some
possibly complex data from each text file ...
=over 4
=item *
Rewrite the callback OOFileFind::_wantedexample() to suit your purpose
+.
You can pass to it any number of arguments via $self
and collect any number of result data items into hashes or arrays atta
+ched to $self.
No global variables are needed.
=item *
Create an instance OOFileFind, call its find(), and use the data colle
+cted by _wantedexample().
=back
=head1 SEE ALSO
File::Find family of modules on CPAN
=head1 LICENSE
Copyright (C) 2006 Rudi Farkas. License hereby
granted for anyone to use, modify or redistribute this module as
they like.
=head1 AUTHOR
Rudi Farkas <rudif@lecroy.com>
|