Mor*_*nar 45 perl file-io scope
我有两个关于Perl open函数的问题:
1)我似乎记得Perl最佳实践中的3参数版本open比两个参数版本更好,例如
open(OUT, '>>', $file);
Run Code Online (Sandbox Code Playgroud)
与
open(OUT, ">>$file");
Run Code Online (Sandbox Code Playgroud)
这是为什么?我试图告诉别人前几天使用3参数版本,但似乎无法用任何东西支持它.
2)我似乎还记得autovivified文件句柄比bareword文件句柄更受青睐(他们称之为不同的东西)?而且也记不住为什么,例如
open(my $out, '>>', $file);
Run Code Online (Sandbox Code Playgroud)
与
open(OUT, '>>', $file);
Run Code Online (Sandbox Code Playgroud)
这是strict件事吗?我似乎记得能够使用OUT,strict但我不记得了.
Mar*_*rkR 64
OUT)不是一个好主意,因为它们在整个程序中是全局的 - 您需要确保没有其他例程(包括模块中的例程)使用相同的名称(包括将来).my $f; open $f, ">$some_filename";,暴露于$some_filename包含前导的bug >会改变程序的行为.使用三参数形式通过将模式和文件名分离为不能干涉的单独参数来避免这种情况.
此外,使用带有管道的大量参数形式是一个非常好的主意:
open $pipe, '|-', 'sendmail', 'fred@somewhere.fake';
Run Code Online (Sandbox Code Playgroud)
比将它作为单个字符串更好 - 它避免了可能的shell注入等.
mob*_*mob 16
解决#2:
OUT 是一个全局文件句柄,并使用它暴露你这样的阴险错误:
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;
Run Code Online (Sandbox Code Playgroud)
dla*_*and 13
要记住的一个方面是两个arg形式被打破.考虑一个名为"abc"的文件(即带有前导空格的文件名).你无法打开文件:
open my $foo, ' abc' or die $!;
open my $foo, '< abc' or die $!;
open my $foo, '< abc' or die $!;
# nothing works
Run Code Online (Sandbox Code Playgroud)
空间被删除,因此无法再找到该文件.这种情况非常不可能,但绝对是一个问题.三个arg形式免疫这个:
open my $foo, '<', ' abc' or die $!;
# works
Run Code Online (Sandbox Code Playgroud)
来自perlmonks的这个帖子与任何问题一样好.请记住,在2001年,三arg形式仍然被认为是新的,因此不适用于可移植代码,因为如果在5.005解释器上运行,Perl程序将因语法错误而死亡.现在不再是这种情况了:perl 5.005已被弃用,已经过时了.