I've got two questions about the Perl open
function:
1) I seem to remember from Perl Best Practices that the 3-argument version of open
is better than the two argument version, e.g.
open(OUT, '>>', $file);
vs.
open(OUT, ">>$file");
Why is that? I was trying to tell somebody to use the 3-argument version the other day but couldn't seem to back it up with anything.
2) I also seem to remember autovivified filehandles being favored over bareword filehandles (they called something different)? And also couldn't remember why, e.g.
open(my $out, '>>', $file);
vs.
open(OUT, '>>', $file);
Is it a strict
thing? I seem to remember being able to use OUT
with strict
but I can't remember.
OUT
) is not a good idea, as they are global across your entire program - you need to be sure that no other routine including those in modules are using the same name (including in the future).my $f; open $f, ">$some_filename";
is exposed to the bug where $some_filename
containing a leading >
will change the program's behaviour.Using the three-argument form avoids this by separating the mode and filename into separate arguments where they can't interfere.
Moreover, using the lots-of-arguments form with pipes is a very good idea:
open $pipe, '|-', 'sendmail', '[email protected]';
Is better than doing it all as a single string – it avoids possible shell injection etc.
Tackling #2:
OUT
is a global filehandle and using it exposes you to insidious bugs like this:
sub doSomething {
my ($input) = @_;
# let's compare $input to something we read from another file
open(F, "<", $anotherFile);
@F = <F>;
close F;
&do_some_comparison($input, @F);
}
open(F, "<", $myfile);
while (<F>) {
&doSomething($_); # do'h -- just closed the F filehandle
}
close F;
One aspect to keep in mind is that the two-arg form is broken. Consider a file named ' abc' (that is, a file name with a leading blank). You cannot open the file:
open my $foo, ' abc' or die $!;
open my $foo, '< abc' or die $!;
open my $foo, '< abc' or die $!;
# nothing works
The space gets dropped and so the file can no longer be found. Such a scenario is highly improbable, but definitely a problem. The three-arg form is immune to this:
open my $foo, '<', ' abc' or die $!;
# works
This thread from perlmonks is as good a discussion as any of the issue. Just bear in mind that in 2001, the three-arg form was still considered new, and thus not suitable for portable code, since Perl programs would die with a syntax error if run on a 5.005 interpreter. This is no longer the case: perl 5.005 is beyond deprecated, it is obsolete.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With