tags:

views:

85

answers:

5

I have basically the following perl I'm working with:

open I,$coupon_file or die "Error: File $coupon_file will not Open: $! \n";
while (<I>) {
 $lctr++;
 chomp;
 my @line = split/,/;
 if (!@line) {
     print E "Error: $coupon_file is empty!\n\n";
     $processFile = 0; last;
 }
}

I'm having trouble determining what the split/,/ function is returning if an empty file is given to it. The code block if (!@line) is never being executed. If I change that to be

if (@line)

than the code block is executed. I've read information on the perl split function over at http://perldoc.perl.org/functions/split.html and the discussion here about testing for an empty array but not sure what is going on here.

I am new to Perl so am probably missing something straightforward here.

Thanks.

A: 

Empty file or empty line? Regardless, try this test instead of !@line.

if (scalar(@line) == 0) {
    ...
}

The scalar method returns the array's length in perl.

Some clarification:

if (@line) {
}

Is the same as:

if (scalar(@line)) {
}

In a scalar context, arrays (@line) return the length of the array. So scalar(@line) forces @line to evaluate in a scalar context and returns the length of the array.

xyld
So using just if (@line) is testing that the array is defined or exists and NOT the size of the array?
Casey
its perl using context's to determine what its going to do. `if (@line)` is the same as `if (scalar(@line))`, but with the `!@line`, you're not guarantee'ing its being evaluated in a `scalar` context.
xyld
No. `if (@line)` is the same as `if (scalar(@line))`, which evaluates to true whenever there are elements in the list.
jamessan
btw, just tested `!@line` and its the same as `scalar(@line) == 0`, so no real biggie there. Regardless, eugene has a good point that the `if (!@line)` won't happen at all if the file is empty.
xyld
+5  A: 
  1. If the file is empty, the while loop body will not run at all.
  2. Evaluating an array in scalar context returns the number of elements in the array.

    split /,/ always returns a 1+ elements list if $_ is defined.

eugene y
A: 

I'm not sure whether you're trying to detect if the line is empty (which your code is trying to) or whether the whole file is empty (which is what the error says).

If the line, please fix your error text and the logic should be like the other posters said (or you can put if ($line =~ /^\s*$/) as your if).

If the file, you simply need to test if (!$lctr) {} after the end of your loop - as noted in another answer, the loop will not be entered if there's no lines in the file.

DVK
+2  A: 

You might try some debugging:

...
chomp;

use Data::Dumper;
$Data::Dumper::Useqq = 1;

print Dumper( { "line is" => $_ } );
my @line = split/,/;
print Dumper( { "split into" => \@line } );

if (!@line) {
...
ysth
And of course, always **always** use `use strict; use warnings;` in every single file.
Ether
+1  A: 
Greg Bacon