From: Gunnar Hjalmarsson <[EMAIL PROTECTED]>
> Ron Goral wrote:
> > I am having some difficulty with a module that is using File::Find.
> > The method is below.
> > 
> > The idea is to enter this method feeding it a file name and
> > beginning directory and then looking for all occasions of
> > $file_name and push those addresses into @a_files.  This works fine
> > until I need to use FindPath again during the same session.  What
> > I'm finding is that while @a_files looses scope within FindPath
> > itself, it does not in ProcessFile.  In other words, when I exit
> > FindPath and come back into it later, @a_files is an uninitiated
> > array.  However when ProcessFile is called, @a_files has retained
> > the values it had from the last call to FindPath.
> > 
> > Am I making sense?
> 
> Yes. But you are apparently running the code without warnings enabled,
> or else Perl would have indicated the reason for this problem.
> 
> > sub FindPath
> >     {
> >     #- Var Declaration And Initialization
> >     my ($hr_self, $file_name, $file_path) = @_;
> >     # Array to fill with file paths
> >     my @a_files = ();
> > 
> >     # Search file_path for the file
> >     find(\&ProcessFile, $file_path);
> > 
> >     #- The Subroutine To Process Files And Directories
> >     sub ProcessFile
> >         {if ($_ eq $file_name){push (@a_files, $File::Find::name);}}
> > 
> >     # Return the paths found
> >     return @a_files;
> >     }   # end FindPath
> 
> One possible solution is to move the ProcessFile() function out from
> FindPath(), so the former is no longer a nested sub:
> 
>      sub ProcessFile {
>          my ($a_files, $file_name) = @_;
>          push @$a_files, $File::Find::name if $_ eq $file_name;
>      }
> 
> and call ProcessFile() from FindPath() with arguments:
> 
>      find( \&ProcessFile( [EMAIL PROTECTED], $file_name ), $file_path );

You can't do that. You'd have to write it like this:

        find( sub {ProcessFile( [EMAIL PROTECTED], $file_name )}, $file_path );

Another option would be to use an unnamed subroutine like this:

sub FindPath
    {
    #- Var Declaration And Initialization
    my ($hr_self, $file_name, $file_path) = @_;
    # Array to fill with file paths
    my @a_files = ();

    # Search file_path for the file
    find(sub {
                if ($_ eq $file_name){push (@a_files, $File::Find::name);}
        }, $file_path);

    # Return the paths found
    return @a_files;
    }   # end FindPath


Or (which might very well be fastest) you'd declare the $file_name 
and @a_files outside the FindPath and ProcessFile:

{
  my ($file_name, @a_files);

  sub FindPath
    {
    #- Var Declaration And Initialization
        my ($hr_self, $file_path);
    ($hr_self, $file_name, $file_path) = @_;
    # Array to fill with file paths
    @a_files = ();

    # Search file_path for the file
    find(\&ProcessFile, $file_path);

    # Return the paths found
    return @a_files;
  }   # end FindPath

  #- The Subroutine To Process Files And Directories
  sub ProcessFile {
    if ($_ eq $file_name){push (@a_files, $File::Find::name);}
  }
}

HTH, Jenda
===== [EMAIL PROTECTED] === http://Jenda.Krynicky.cz =====
When it comes to wine, women and song, wizards are allowed 
to get drunk and croon as much as they like.
        -- Terry Pratchett in Sourcery


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to