Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么使用Autovified filehandles的三参数开放调用是Perl的最佳实践?_Perl_File Io_Scope - Fatal编程技术网

为什么使用Autovified filehandles的三参数开放调用是Perl的最佳实践?

为什么使用Autovified filehandles的三参数开放调用是Perl的最佳实践?,perl,file-io,scope,Perl,File Io,Scope,关于Perlopen函数,我有两个问题: 1) 我似乎从Perl最佳实践中记得,3参数版本的open比两参数版本更好,例如 open(OUT, '>>', $file); vs 为什么呢?前几天我试图告诉某人使用3参数版本,但似乎没有任何支持 2) 我似乎还记得,与裸字文件句柄相比,自动激活的文件句柄更受青睐(他们称之为不同的东西)?也不记得为什么,例如 open(my $out, '>>', $file); vs 这是严格的吗?我似乎记得能够使用OUT和strict

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

1) 我似乎从Perl最佳实践中记得,3参数版本的
open
比两参数版本更好,例如

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

为什么呢?前几天我试图告诉某人使用3参数版本,但似乎没有任何支持

2) 我似乎还记得,与裸字文件句柄相比,自动激活的文件句柄更受青睐(他们称之为不同的东西)?也不记得为什么,例如

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

这是严格的吗?我似乎记得能够使用
OUT
strict
但我不记得了。

处理#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;
sub-doSomething{
我的($input)=@;
#让我们将$input与从另一个文件读取的内容进行比较
开放式(F,“
  • 将typeglobs用于文件句柄(如
    OUT
    )不是一个好主意,因为它们在整个程序中都是全局的-您需要确保没有其他例程(包括模块中的例程)使用相同的名称(包括将来)
  • 使用open的双参数形式会使应用程序暴露于由包含特殊字符的变量引起的错误行为,例如
    my$f;open$f,“>$some\u filename”
    会暴露于错误中,其中
    $some\u filename
    包含前导
    将更改程序的行为
使用三参数形式可以避免这种情况,方法是将模式和文件名分离为单独的参数,在这些参数中它们不会相互干扰

此外,将大量参数表单与管道一起使用是一个非常好的主意:

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

比做一个字符串要好得多——它避免了可能的shell注入等。

< P>一个方面要记住的是,两个ARG格式被破坏了。考虑一个名为“ABC”的文件(即,一个带超前空白的文件名)。不能打开文件:

open my $foo, ' abc' or die $!;
open my $foo, '< abc' or die $!;
open my $foo, '<  abc' or die $!;
# nothing works
打开我的$foo、'abc'或die$!;
打开我的$foo,“
空间被删除,因此无法再找到文件。这种情况极不可能发生,但肯定是个问题。三个arg表单对此免疫:

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

打开我的$foo,'啊,这是一个非常可靠的推理。谢谢MarkR。这正是我所寻找的答案。很高兴知道我在过去几年中以这种方式做这件事有一个合理的理由。关于兼容性的说明:3-arg打开和
打开我的$fh,
从5.6.0开始。
打开我的$fh,“|-”,列表
(列表管道打开)从5.8.0开始工作。没有理由对已知内容的文本使用难看的pipe open形式,例如建议的那种形式。此外,您打破了复杂管道的外壳处理。糟糕。我还想指出,Autovified filehandles更容易作为参数传递给方法和子例程。您甚至可以打开dupe:这是因为Perl::Critic建议这样做:)不是dupe,这是在问为什么这样做是最好的方法。很抱歉编辑…我从来没有听说过这些称为“Autovified filehandles”(我总是听到“词法filehandle”)并且试图提高搜索能力,但现在我看到autovivification真的涉及到了,文档确实是这样引用它们的。回滚到以前的版本。不,open的两个参数形式,或者一个参数形式,并没有被破坏。它按照设计、文档和广告的方式工作。它可能就是神奇的open Isn不是您所需要的。另一个打开的三参数插件是中间参数可以(通常应该)包括流的编码。
open my $foo, ' abc' or die $!;
open my $foo, '< abc' or die $!;
open my $foo, '<  abc' or die $!;
# nothing works
open my $foo, '<', ' abc' or die $!;
# works