Question

I'm using the File::Find module to traverse a directory tree. Once I find a specific file, I want to stop searching. How can I do that?

   find (\$processFile, $mydir);

   sub processFile() {
      if ($_ =~ /target/) {
         # How can I return from find here?
      }
   }
Was it helpful?

Solution

Seems like you will have to die:

eval {
    find (\$processFile, $mydir);
};

if ( $@ ) {
   if ( $@ =~ m/^found it/ ) {
        # be happy
    }
    else ( $@ ) {
        die $@;
    }
}
else {
   # be sad
}


sub processFile() {
   if ($_ =~ /target/) {
      die 'found it';
   }
}

OTHER TIPS

In addition to what everyone else said, you may wish to take a look at File-Find-Object, which is both iterative (and as such capable of being interrupted in the middle) and capable of instantiation (so you can initiate and use several at once, or instantiate an F-F-O object based while performing another scan, etc.)

The downside for it is that it isn't core, but it only has Class::Accessor as a dependency, and is pure-Perl so it shouldn't be hard to install.

I should warn you that I am its maintainer, so I may be a bit biased.

Can you throw custom exceptions in Perl?

You could use named blocks and jump to it if you find your result (with next, last, it depends from what you need).

I found this link:

http://www.perlmonks.org/index.pl?node_id=171367

I copied one of the scripts in that list of posts, and this seems to work:

#! /usr/bin/perl -w

use strict;
use File::Find;

my @hits = ();
my $hit_lim = shift || 20;

find(
    sub {
        if( scalar @hits >= $hit_lim ) {
            $File::Find::prune = 1;
            return;
        }
        elsif( -d $_ ) {
            return;
        }
        push @hits, $File::Find::name;
    },
    shift || '.'
);

$, = "\n";
print @hits, "\n";

It appears that is actually causing find to not traverse any more by using $File::Find::prune.

The function processFile() should return true if it finds the file, and false otherwise. So, every time that processFile calls himself should check this return value. If it is true, some recursive call has found the file, so there's no need to call himself again, and it must also return true. If it's false, the file hasn't been found yet, and it should continue the search.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top