> -----Original Message-----
> From: Gunnar Hjalmarsson [mailto:[EMAIL PROTECTED]
> Sent: Sunday, October 10, 2004 6:32 PM
> To: [EMAIL PROTECTED]
> Subject: Re: Variable scope in wanted function
>
>
> 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 );
>
> And last but not least:
>
>      use warnings;
>
> ;-)
>
> --
> Gunnar Hjalmarsson
> Email: http://www.gunnar.cc/cgi-bin/contact.pl

Actually, I am using warnings. However, in the 'real' code, I have placed
the the call to 'find' within an eval block so that I can manage the errors.
Is this why I did not receive any warnings? The difficulties with moving
ProcessFile out of FindPath is that any return values ProcessFile might have
are ignored and it can take no arguments (this is from
http://search.cpan.org/~nwclark/perl-5.8.5/lib/File/Find.pm#The_wanted_funct
ion).

I've setting up a "global" variable like $hr_self->{a_files}, where $hr_self
is an object ref to the module.  This requires calling ProcessFile like so:

find(\$hr_self->ProcessFile, $file_path);
or
find(\&ProcessFile($hr_self), $file_path);

File::Find dies here with the complaint "invalid top directory at
/usr/lib/perl5/5.6.1/File/Find.pm line 295, line 36."  I'm fairly certain
this is because of the '$hr_self->'.  I'm also completely out of ideas for
this.  At least when ProcessFile is defined within FindPath, the only
variable trouble I had was with @a_files.

There is a light, however.  If ProcessFile is actually an anonymous sub and
called this way:

my $processfile = sub {if ($_ eq $file_name){push (@a_files,
$File::Find::name);}};

find(\&$processfile, $file_path);

There are no errors and @a_files is populated (and depopulated) as it should
be.

Thanks for taking the time to check this out and to write an answer.



-- 
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