Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Wanet Telecoms Ltd on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

File Test operator in an array

Status
Not open for further replies.

Ramnarayan

Programmer
Jan 15, 2003
56
US
Hi,

I am trying to figure why PERL is giving a warning "Use of uninitialized value in -e at abc.pl line 16". I wantedly made sure that I tested that the script should work for gml files present under sss/ directory. But if they are not there, it should issue the errror "Can't find any GML files!:". I am not understanding where the warning is coming from. How to remove the warning?

Here is the script....


#!/usr/local/bin/perl -w

my $whoami = ($0 =~ m,([^/\\]*)$,) ? $1 : $0;

my $errors = 0;
use strict;

my $dir = "sss/";
my @gmlfiles = glob("${dir}*.gml");
my $gmlfiles = shift(@gmlfiles);
my $abs_found = 0;
my $bib_found = 0;
my $abs_notfound = 0;
my $gmlfile = 0;

if (-e $gmlfiles)
{
foreach(@gmlfiles)
{
my $gml = $_;
$gmlfile ++;
open (GML, "<$gml") or fatal ("Can't open $gml for read access: $!\n");
while(<GML>)
{
my $line = $_;
if ($line =~ m/\<abs\>/)
{
$abs_found++;
}
if ($line =~ m/\<bib\>/)
{
$bib_found++;
}
}
}
}
else
{
fatal("Can't find any GML files!:\n");
}
 
You are shifting $gmlfiles out of the array and then testing it. If the array is empty, $gmlfiles would be undefined and you'd get the error that you do.

You should always hear alarm bell ringings when you use a variable (like $gmlfiles) which really has nothing to do with the problem itself. You should test whether the glob has returned anything by counting the number of values in @gmlfiles. A simple way would be
Code:
#!/usr/local/bin/perl -w
use strict;

my $whoami = ($0 =~ m,([^/\\]*)$,) ? $1 : $0;

my $dir = "sss/";
my @gmlfiles = glob("${dir}*.gml");
fatal("Can't find any GML files!:\n") unless @gmlfiles;

my( $errors, $abs_found, $bib_found, $abs_notfound, $gmlfile ) = (0,0,0,0,0);

foreach my $gml (@gmlfiles) { [green]# name your iterator here[/green]
  ++$gmlfile;
  local *GML; [green]# local filehandles autoclose on block exit[/green]
  open (GML, "<$gml")
    or fatal ("Can't open $gml for read access: $!\n");
  while(<GML>) { [green]# much neater with default iterator $_[/green]
    ++$abs_found if /<abs>/; [green]# don't need to \escape < or >[/green]
    ++$bib_found if /<bib>/;
  }
}

Have a look through the rest of my re-write - I've used a couple of techniques you may find useful.

Yours,

fish



&quot;As soon as we started programming, we found to our surprise that it wasn't as easy to get programs right as we had thought. Debugging had to be discovered. I can remember the exact instant when I realized that a large part of my life from then on was going to be spent in finding mistakes in my own programs.&quot;
--Maurice Wilkes
 
I'd avoid using $gmlfiles and @gmlfiles as variables, if I were you, as $gmlfiles is already a scalar which indicates the number of elements in the @gmlfiles array.

The reason for the warning is most likely that you haven't prefaced to the $dir variable to the filename.

Try changing the variable names and adding $dir to the filename, and see how you get on

--Paul

Spend an hour a week on CPAN, helps cure all known programming ailments ;-)
 
I think this will happen if there are no gml files - due to the -w switch


Kind Regards
Duncan
 
Paul - I think you meant $#gmlfiles


Yours,

fish

&quot;As soon as we started programming, we found to our surprise that it wasn't as easy to get programs right as we had thought. Debugging had to be discovered. I can remember the exact instant when I realized that a large part of my life from then on was going to be spent in finding mistakes in my own programs.&quot;
--Maurice Wilkes
 
Your warning is coming on for this line
Code:
if (-e $gmlfiles)
perl looks like shell but is not
so change the above line to
Code:
if ($gmlfiles)
and also alter the lines that are marked with red
Code:
#!/usr/local/bin/perl -w

my $whoami = ($0 =~ m,([^/\\]*)$,) ? $1 : $0;

my $errors = 0;
use strict;

my $dir = "sss/";
my @gmlfiles = glob("${dir}*.gml");
my $gmlfiles = shift(@gmlfiles);
my $abs_found = 0;
my $bib_found = 0;
my $abs_notfound = 0;
my $gmlfile = 0;

[red]if ($gmlfiles)[/red]
{
    foreach(@gmlfiles)
    {
        my $gml = $_;
        $gmlfile ++;
        [red]print "$gml\n";[/red]
        open (GML, "[red]$gml[/red]") or [red]die[/red] ("Can't open $gml for read access: $!\n");
        while(<GML>)
        {
            my $line = $_;
            if ($line =~ m/\<abs\>/)
            {
                $abs_found++;
            }
            if ($line =~ m/\<bib\>/)
            {
                $bib_found++;
            }
        }
        [red]close GML;[/red]
    }
}
else
{
    [red]die[/red]("Can't find any GML files!:\n");
}
unless you have later on your code, something that defines 'main::fatal'


``The wise man doesn't give the right answers,
he poses the right questions.''
TIMTOWTDI
 
Pengo, that's still broken. If the glob returns precisely one element, it is shifted into $gmlfiles and then ignored. Also, -e is perfectly valid in perl.

f

&quot;As soon as we started programming, we found to our surprise that it wasn't as easy to get programs right as we had thought. Debugging had to be discovered. I can remember the exact instant when I realized that a large part of my life from then on was going to be spent in finding mistakes in my own programs.&quot;
--Maurice Wilkes
 

Well the guy shifts it anyway from the array(unless he didn't want to, and he made a mistake understanding what 'shift' does), so that means it will be ignored when it comes to check the @gmlfiles.

I know all about unary operators. Sometimes though it seems that they don't work very good with filenames in variables, but they work fine with filehandles.


``The wise man doesn't give the right answers,
he poses the right questions.''
TIMTOWTDI
 
unless he didn't want to
I'm sure it's the latter, otherwise the code would process every .gml file in the directory except the first, alphabetically. That's so unusual that it would deserve a comment in the code, if only to stop yourself noticing it years later and absent-mindedly "fixing" it.

In any case, if he really did want to shift the first filename out and then test it for existance, it would still give the "uninitialised string" error if there were no files. If the aim is to ignore it, why test it for existance anyway?

If the OP was still around, he could tell us....


f

PS,
they don't work very good with filenames
If you're finding bugs in perl, you should report them so that they can be fixed or you might as well use VB. As there are no open, relevant bug reports about the unary file test operators, it would seem that they affect you alone, which would suggest a problem with your perl build.

&quot;As soon as we started programming, we found to our surprise that it wasn't as easy to get programs right as we had thought. Debugging had to be discovered. I can remember the exact instant when I realized that a large part of my life from then on was going to be spent in finding mistakes in my own programs.&quot;
--Maurice Wilkes
 
Strange things are happening when you experiment while compiling perl and you put your fingers on the source code !!!


``The wise man doesn't give the right answers,
he poses the right questions.''
TIMTOWTDI
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top