开发者

What are the differences between these "open" formats

I use this syntax to open my files, since I learned that some years ago in a training and the books I have do it the same way.

open( INPUTFILE, "< $input_file" ) || die "Can't open $input_file: $!";

Some days ago i saw in a SO answer this form:

open( $input_file, "<", $input_fi开发者_开发技巧le ) || die "Can't open $input_file: $!";

Is this format new or just doing the same, a different way, using a normal variable as filehandle?

Should I change to the "new" format? Does it have some advantages, or does the "old" format have some disadvantages?


You should use the three-argument version because it protects against files with crazy names. Consider the following:

my $file = "<file.txt";
open( INPUTFILE, "< $file" ) or die "$!";

This will interpolate as:

open( INPUTFILE, "< <file.txt" ) or die "$!";

...meaning you'll actually open a file named file.txt instead of one named <file.txt.

Now, for the filehandle, you want to use a lexical filehandle:

open( my $fh, "<", $file.txt ) or die "$!";

The reason for this is when $fh goes out of scope, the file closes. Further, the other type of filehandle (I can't remember what it's called) has global scope. Programmers aren't all that imaginative, so it's likely that you'll name your filehandle INPUTFILE or FH or FILEHANDLE. What happens if someone else has done the same, named their filehandle INPUTFILE, in a module you use? Well, they're both valid and one clobbers the other. Which one clobbers? Who knows. It's up to the ordering of when they're opened. And closing? And what happens if the other programmer has opened INPUTFILE but actually opened it for write? Worlds end, my friend, worlds end.

If you use a lexical filehandle (the $fh) you don't have to worry about worlds ending, because even if the other programmer does call it $fh, variable scope protects you from clobbering.

So yes, always use the three-argument form of open() with lexical filehandles. Save the world.


The difference between the two argument form of open and the three argument form has to do with how the filename is treated when it contains special characters. For example, in a two argument open, if the filename contains the | character, or a number of other special characters, the file will be opened with the shell. Thus with the two argument open it is possible to write something like this:

 open my $file, 'rm -rf * |';

and perl will happily open a pipe to the output of rm while it runs deleting your system.

Whereas if you use the three argument form of open, the filename is never passed through the shell, which is far safer, if you are getting your filename from an untrusted source.

I also find the three argument form to be less ambiguous because it forces you to specify if you are reading, writing, or appending.

You can get all of the gory details of open on the manual page.


From the perl tutorial

There is also a 3-argument version of open, which lets you put the special redirection characters into their own argument:

open( INFO, ">", $datafile ) || die "Can't create $datafile: $!";

In this case, the filename to open is the actual string in $datafile , so you don't have to worry about $datafile containing characters that might influence the open mode, or whitespace at the beginning of the filename that would be absorbed in the 2-argument version. Also, any reduction of unnecessary string interpolation is a good thing.

So the 3 arguments version of the open is the safest to use.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜