Link to home
Start Free TrialLog in
Avatar of sini_m
sini_m

asked on

How to retuen a value while using File::Find

Hi,
I have two subroutines

sub xcheck
{
  ## get the $directory after some code lines.
  find (\&xlength , $directory);

}

sub xlength
  {
   
  my $file = $File::Find::name;
  if(-f $file)
   {
   open(FILE, "<$file") || die "Can't open $file $!\n";
   my @lines = <FILE>;
   close(FILE);
   }
    ## do some operation on each of the files in $directory.
    push (@errorMessage, "error messages");
 return   @errorMessage;     ##==> I want this return value.
 }
 
 
 How can I return a value while using find?
 I have tried
 find (\&xlength(\@errorMessage), $directory);
 
 and updating the reference in xlength.
 But File::Find doesn't work then.
 
Thanks

Sini
Avatar of inq123
inq123

Hi sini_m,

One possibility is to declare a global arrayref variable and use that variable in place of the @errorMessage in your xlength().  That way you just read the content of the arrayref after calling find() and you don't have to worry about returning any data from xlength.

Cheers!
ASKER CERTIFIED SOLUTION
Avatar of kandura
kandura

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ozo

sub xcheck
{
  local @errorMessage;
  ## get the $directory after some code lines.
  find (\&xlength , $directory);
  return   @errorMessage;     ##==> I want this return value.
}

sub xlength
  {
   
  my $file = $File::Find::name;
  if( -f )
   {
   open(FILE, "<$file") || die "Can't open $file $!\n";
   my @lines = <FILE>;
   close(FILE);
   }
    ## do some operation on each of the files in $directory.
    push (@errorMessage, "error messages");
 }
Avatar of sini_m

ASKER

Hi,

I just tried out ozo's comment.
---------------
Global symbol "@errorMessage" requires explicit package name at test.pl line 5.
Execution of test.pl aborted due to compilation errors.
--------------

I am using use strict;

 inq123, I failed to mention I shouldn't be using any global variables. These subroutines go into a package. Can't use any package wide variables. Is 'local' like a global variable?

I am going to try out kandura's comment.
Thanks for the help.

Sini


Avatar of sini_m

ASKER

Hi,

Kandura's solution did the work for me.

sub init
{
  print map { $_.$/ } xcheck('.');
}

&init;

Thanks for all the solutions offered.
Sini
use strict;
use warnings;
use File::Find;
my $directory='testdir';
sub xcheck
{
  local @::errorMessage;
  ## get the $directory after some code lines.
  find (\&xlength , $directory);
  return   @::errorMessage;     ##==> I want this return value.
}

sub xlength
  {
   
  my $file = $File::Find::name;
  if( -f )   {
   open(FILE, "<$_") || die "Can't open $file $!\n";
   my @lines = <FILE>;
     close(FILE);
   }
    ## do some operation on each of the files in $directory.
    push (@::errorMessage, "error messages");
 }

print join"\n",xcheck();
sini_m, if you can't use global, then I prefer ozo's solution (no offense to Kandura's nice solution).  

local is not global.  It localizes the variable to the current lexical scope AND all the subs called after the local declaration.  So it's kinda like a localized global and it'd better solve your package concerns.  

But frankly, even if you put those subs into a package, there's no rule that says global variables cannot be used.  If you declare these global variables with 'my', then the other packages and calling programs of your package won't be able to access it either (no accidental usage or non-permitted access).  

Further, I personally think the access control in Perl is maybe "nice style" but in actuality ridiculous, since its source code is in plain daylight for everyone to see/change.
Avatar of sini_m

ASKER

Hi,

It is a package a lot of people are developing. We write subroutines for various 'checks' and put them into an existing package. It is kind of a continuing process.  I will try out ozo's new comment. If

local @::errorMessage  and
@::errorMessage

are different in behaviour, maybe I could use this.

Thanks
Sini
I see.  But wouldn't it be better to have each person/group to contribute to a separate package?  It sounds (more than) a bit messy to have everybody contributing to one big test package.
Avatar of sini_m

ASKER

Hi inq123,

Yes, It is not the best solution. But an 'engine' that runs theses rules takes into account only a couple of packages, so we have to fit everything into it. Or redesign the engine.
Why not let your engine take in a Config.pm, in which all the new test modules are added.  Each test programmer maintains his/her own modules, just add the module names to Config.pm.  All the functions can be exported in those separate test modules and any package variables can be used safely.  Requires little effort to do it this way.
Avatar of sini_m

ASKER

Hi inq123,

Guess we could consider it. There might be objection to any change now, but let me see. :) Thanks.