开发者

Why am I getting a closed filehandle error when using the diamond operator in list context in Perl?

开发者 https://www.devze.com 2022-12-28 14:16 出处:网络
This code: foreac开发者_如何学Ch my $file (@data_files) { open my $fh, \'<\', $file || croak \"Could not open file $file!\\n\";

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";
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号