http://qs321.pair.com?node_id=549365
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>