为什么使用自动生成文件句柄的三参数打开调用是Perl的最佳实践?

时间:2009-09-25 21:51:53

标签: perl file-io scope

我有两个关于Perl open函数的问题:

1)我似乎记得 Perl Best Practices open的3参数版本比两个参数版本更好,例如

open(OUT, '>>', $file);

VS

open(OUT, ">>$file");

为什么?我试图告诉别人前几天使用3参数版本,但似乎无法用任何东西支持它。

2)我似乎还记得autovivified文件句柄比bareword文件句柄更受青睐(他们称之为不同的东西)?而且也记不住为什么,例如。

open(my $out, '>>', $file);

VS

open(OUT, '>>', $file);

strict的事吗?我似乎记得能够将OUTstrict一起使用,但我记不住了。

3 个答案:

答案 0 :(得分:64)

  • 使用typeglobs作为文件句柄(如OUT)并不是一个好主意,因为它们在整个程序中是全局的 - 您需要确保没有其他例程(包括模块中的例程)使用相同的名称(包括在将来)。
  • 使用双参数形式的open将您的应用程序暴露给由包含特殊字符的变量引起的错误行为,例如my $f; open $f, ">$some_filename";会出现$some_filename包含前导>的错误将改变程序的行为。

使用三参数形式可以通过将模式和文件名分隔成不会干扰的单独参数来避免这种情况。

此外,使用带有管道的大量参数形式是一个非常好的主意:

open $pipe, '|-', 'sendmail', 'fred@somewhere.fake';

比将所有内容作为单个字符串更好 - 它避免了可能的shell注入等。

答案 1 :(得分: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;

答案 2 :(得分:13)

要记住的一个方面是两个arg形式被打破。考虑一个名为“abc”的文件(即带有前导空格的文件名)。您无法打开文件:

open my $foo, ' abc' or die $!;
open my $foo, '< abc' or die $!;
open my $foo, '<  abc' or die $!;
# nothing works

空间被删除,因此无法再找到该文件。这种情况非常不可能,但绝对是一个问题。三个arg形式对此免疫:

open my $foo, '<', ' abc' or die $!;
# works
来自perlmonks的

This thread与任何问题一样好。请记住,在2001年,三个arg表单仍然被认为是 new ,因此不适合于可移植代码,因为如果在5.005解释器上运行,Perl程序会因语法错误而死亡。现在不再是这种情况了:perl 5.005已被淘汰,已经过时了。