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
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)
and updating the reference in xlength.
But File::Find doesn't work then.
Thanks
Sini
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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");
}
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
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
ASKER
Hi,
Kandura's solution did the work for me.
sub init
{
print map { $_.$/ } xcheck('.');
}
&init;
Thanks for all the solutions offered.
Sini
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();
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.
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.
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
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.
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.
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.
ASKER
Hi inq123,
Guess we could consider it. There might be objection to any change now, but let me see. :) Thanks.
Guess we could consider it. There might be objection to any change now, but let me see. :) Thanks.
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!