Perl split into empty file
I have basically the following perl that I am 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 figuring out what the split / function returns, / if it is assigned an empty file. The if (! @Line) code block is never executed. If I change this as
if (@line)
than the code block is executed. I've read the information about perl splitting function at http://perldoc.perl.org/functions/split.html and the discussion here about testing on an empty array, but not sure what is going on here.
I'm new to Perl, so there probably isn't anything simple here.
a source to share
Here are some tips to make your code more idiomatic:
- the special variable
$.
already contains the current line number, so you can get rid of it sooner$lctr
. - Are blank lines really errors or can you ignore them?
- Pull down the list returned from
split
and give the names of the parts. - Let Perl make a discovery with the "diamond operator" :
File descriptor null
<>
is special: it can be used to emulate the behavior ofsed
andawk
. Input from<>
comes either from standard input or from each file specified on the command line. Here's how it works: the first time the<>
array is evaluated@ARGV
, and if it is empty, it is$ARGV[0]
set to"-"
, which gives you standard input when opened. The array is@ARGV
then processed as a list of filenames. Cyclewhile (<>) { ... # code for each line }
is equivalent to the following Perl-like pseudocode:
unshift(@ARGV, '-') unless @ARGV; while ($ARGV = shift) { open(ARGV, $ARGV); while (<ARGV>) { ... # code for each line } }
except that it is not that cumbersome to say and will actually work.
Say your input is in a file named input
and contains
Campbell soup, 0.50 Mac & Cheese, 0.25
Then with
#! /usr/bin/perl
use warnings;
use strict;
die "Usage: $0 coupon-file\n" unless @ARGV == 1;
while (<>) {
chomp;
my($product,$discount) = split /,/;
next unless defined $product && defined $discount;
print "$product => $discount\n";
}
which we run as shown below on Unix:
$ ./coupons input Campbell soup => 0.50 Mac & Cheese => 0.25
a source to share
Empty file or empty line? Regardless, try this test instead !@line
.
if (scalar(@line) == 0) {
...
}
The method scalar
returns the length of the array in perl.
Some clarifications:
if (@line) {
}
Same as:
if (scalar(@line)) {
}
In scalar context, arrays ( @line
) return the length of the array. Therefore scalar(@line)
forces the @line
evaluation in a scalar context and returns the length of the array.
a source to share
I'm not sure if you are trying to determine if the line is empty (which is what your code is trying to do) or the entire file is empty (which is what the error says).
If string please correct the error text and the logic should be similar to other posters (or you can put if ($line =~ /^\s*$/)
as your if).
If you want a file, you just need to check if (!$lctr) {}
after the end of your loop - as noted in another answer, the loop will not be entered if there are no lines in the file.
a source to share