?
Solved

How to retuen a value while using File::Find

Posted on 2005-04-26
12
Medium Priority
?
365 Views
Last Modified: 2011-10-03
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
0
Comment
Question by:sini_m
  • 5
  • 4
  • 2
  • +1
12 Comments
 
LVL 8

Expert Comment

by:inq123
ID: 13867217
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!
0
 
LVL 18

Accepted Solution

by:
kandura earned 2000 total points
ID: 13867959
xlength operates on a single filename, so it has no business returning the entire array. I can see why you'd want it to, though. This is probably the easiest way:


    use File::Find;
    use strict;
   
    print map { $_.$/ } xcheck('.');
   
    sub xcheck
    {
        my $directory = shift;
        ## get the $directory after some code lines.
        my @errorMessage;
        find (sub { push @errorMessage, xlength($File::Find::name) }, $directory);
        return @errorMessage;
    }
   
    sub xlength {
        my $file = shift;
        if(-f $file )
        {
            open(my $fh, "<$file") or return "$file: $!";
           
            # @lines = <$fh>;
            #process lines
           
            # a sample file test to show how to return errors
            return "$file: not /a/" unless /a/;
        }
   
        return;    
    }
   
0
 
LVL 85

Expert Comment

by:ozo
ID: 13870078

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");
 }
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:sini_m
ID: 13873010
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


0
 

Author Comment

by:sini_m
ID: 13873074
Hi,

Kandura's solution did the work for me.

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

&init;

Thanks for all the solutions offered.
Sini
0
 
LVL 85

Expert Comment

by:ozo
ID: 13873467
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();
0
 
LVL 8

Expert Comment

by:inq123
ID: 13879155
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.
0
 

Author Comment

by:sini_m
ID: 13882637
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
0
 
LVL 8

Expert Comment

by:inq123
ID: 13886106
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.
0
 

Author Comment

by:sini_m
ID: 13904541
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.
0
 
LVL 8

Expert Comment

by:inq123
ID: 13945168
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.
0
 

Author Comment

by:sini_m
ID: 13954062
Hi inq123,

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

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
There are many situations when we need to display the data in sorted order. For example: Student details by name or by rank or by total marks etc. If you are working on data driven based projects then you will use sorting techniques very frequently.…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Six Sigma Control Plans
Suggested Courses

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question