There's an issue with the subroutine originally posted.
The shift
function expects an array as an argument. The implicit variable inside the foreach
is a scalar.
This means that $fh
remains uninitialized. The reason why it probably goes unnoticed is because (as eugene y points out) lexical filehandles close themselves when they go out of scope.
Incidentally, use warnings;
will notify about such things.
A more idiomatic approach would be to use a while
loop:
sub closef {
while ( my $fh = shift @_ ) {
close $fh;
}
}
For more compact notation, a for
loop is the way to go:
sub closef { close for @_; }
The equivalent with a while
loop is not so readable:
sub closef { close while $_ = shift }
Update
Michael Carman's comment below holds true here. The shift
modifies the array being iterated over, which makes it an unsafe operation. This is, in fact, the problem.