Commits

Anonymous committed 9c19c72

Fixed a bug where the get_current_node_files_list could mess up the
traversal becuase it called recurse. Instead made open_dir memoized in a
way.

Comments (0)

Files changed (3)

lib/File/Find/Object.pm

     $self->dir($top->current_path($from));
     $self->idx($index);
 
-    $self->_was_dir_scanned(0);
+    $self->_last_dir_scanned(undef);
 
     $from->dir($self->dir());
 
     $tree->_target_index(-1);
     $tree->_current_idx(-1);
 
+    $tree->_last_dir_scanned(undef);
+
     return $tree;
 }
 
 sub _recurse
 {
     my ($self, $current) = @_;
+
     $self->check_subdir($current) or 
         return "SKIP";
-    
+
+
     push @{$self->_dir_stack()}, 
         File::Find::Object::PathComponent->new(
             $self,
 
 sub open_dir {
     my ($self, $current) = @_;
-    opendir(my $handle, $current->dir()) or return undef;
+
+    if (defined($current->_last_dir_scanned()) &&
+        ($current->_last_dir_scanned() eq $current->dir()
+       )
+    )
+    {
+        return $current->_open_dir_ret();
+    }
+
+    $current->_last_dir_scanned($current->dir());
+
+    my $handle;
+    if (!opendir($handle, $current->dir()))
+    {
+        return $current->_open_dir_ret(undef);
+    }
     my @files = (sort { $a cmp $b } File::Spec->no_upwards(readdir($handle)));
     closedir($handle);
 
     my @st = stat($current->dir());
     $current->inode($st[1]);
     $current->dev($st[0]);
-    return 1;
+
+
+    return $current->_open_dir_ret(1);
 }
 
 sub set_traverse_to
     # Remming out because it doesn't work.
     # $self->_father($self->_current)->dir($self->_current->dir());
 
-    $self->_recurse($self->_current);
+    $self->_current->dir($self->current_path($self->_current()));
 
-    return [ @{$self->_current->_files()}];
+    # open_dir can return undef if $self->_current is not a directory.
+    if ($self->open_dir($self->_current))
+    {
+        return [ @{$self->_current->_files()}];    
+    }
+    else
+    {
+        return [];
+    }
 }
 
 

lib/File/Find/Object/Base.pm

     _files
     idx
     inode
+    _last_dir_scanned
+    _open_dir_ret
     _traverse_to
-    _was_dir_scanned
 ));
 
 1;
     for my $i (1 .. 7)
     {
         my $file = $ff->next();
-        if ($file eq 
+        # We're doing that because get_current_node_files_list() used to
+        # call ->_recurse() which caused some subtle bugs.
+        my $files_in_node = $ff->get_current_node_files_list();
+        
+        if ($file eq
             $t->get_path("t/sample-data/traverse-2/foo/please-prune-me")
            )
         {
     rmtree($t->get_path("./t/sample-data/traverse-2"))
 }
 
+