Why am I getting a closed filehandle error when using the diamond operator in list context in Perl?
This code:
foreac开发者_如何学Ch my $file (@data_files) {
open my $fh, '<', $file || croak "Could not open file $file!\n";
my @records = <$fh>;
close $fh;
....
}
produces this error:
readline() on closed filehandle $fh at nut_init_insert.pl line 29.
and I have no idea why.
EDIT: The original post had ',' instead of '<' in the open
statement.
You have a typo in the code you posted (the second arg to open
), but that does not explain the error message. The message for that problem would be this:
Unknown open() mode ',' at ...
Your problem is related to precedence. The ||
binds too tightly, causing Perl to treat this entire expression as the 3rd argument to open:
$file || croak $!
As a result, even though open
fails (probably because $file
is not a valid file name), croak
is not executed (because $file
is true and the ||
short-circuits). After the open
fails, your program tries to read some lines from an unopened file handle, and you get this error message:
readline() on closed filehandle $fh at ...
You want to use one of the following instead. The second option works (unlike your code) because or
is low precedence.
open(my $fh, '<', $file) || croak ...;
open my $fh, '<', $file or croak ...;
For details on operator precedence, see perlop. The relevant point in your case is that the ||
operator has higher precedence than the list separator (comma).
There is a typo in 2nd argument to open:
open my $fh, '<', $file || croak "Could not open file $file!\n";
精彩评论