哪一个是好的练习,一个词法文件句柄还是一个typeglob?

有人说,我们应该使用一个词法文件句柄,而不是一个typeglob,像这样:

open $fh, $filename; 

但是大多数Perl书籍,包括The Llama Book ,都使用了一个typeglob,像这样:

 open LOGFILE, $filename; 

那么有什么区别呢? 哪一个被认为是更好的做法?

词法文件句柄可以作为parameter passing,文件句柄不能。 Typeglobs可以(或者至less可以引用它们),但是有点麻烦。 考虑使用词汇variables,并确保首先声明它们,这样你就知道它们是词汇,而不是本地或全球的。 即

 my $fh; open $fh, $filename; 

另外考虑使用IO::HandleIO::File作为选项。 以前是FileHandle但是被下面的ysth通知, FileHandle现在只是反过来使用'IO :: Handle',这对我来说是5.6以来的新闻,但是这里有很多要学习的东西。 🙂

另外,不要忘记use strict 🙂

最早的“美洲驼书”是从1993年开始的,在这之前,词法文件句柄是Perl语言的一部分。 由于各种原因,词法文件句柄是更好的做法。 typeglobs最重要的缺点是

  1. 他们总是在全球范围内,这可能会导致这样一个阴险的错误:

     sub doSomething {
      我($input)= @_;
       #让我们比较$input的东西,我们从另一个文件中读取
      打开(F,“<”,$ anotherFile);
       @F = <F>; 
      closuresF;
       do_some_comparison($ input,@F);
     }
    
    打开(F,“<”,$ myfile);
    而(<F>){
         DoSomething的($ _);  #do'h  - closuresF文件句柄
     }
    closuresF;
    
  2. 他们比一个词法文件句柄更难传递给子程序

    包package1;
    子log_time {#打印时间戳到文件句柄
        我($ fh)= @_;
         print $ fh scalar localtime,“\ n”;
     }
    
     package package2;
    打开GLOB,'>','log1';
    打开$词法,'>','log2';
    
    包1 :: log_time($词汇);  #按预期工作
    包1 :: log_time(GLOB);  #不起作用
    包1 :: log_time( 'GLOB');  #不起作用
    包1 :: log_time(* GLOB);  #作品
    包1 :: log_time(包2 :: GLOB);  #作品
    包1 :: log_time( '包2 :: GLOB');  #作品
    

另请参阅: 为什么使用自动化文件句柄的三参数公开调用是Perl的最佳实践?

使用词法variables时,文件句柄具有这些variables的作用域,并在您离开该作用域时自动closures:

 { open my $fh, '<', 'file' or die $!; # ... # the fh is closed upon leaving the scope } 

所以你不要创build永久的全局variables。

不build议使用typeglob文件句柄,因为如果你不注意,这可能会导致几个问题。 例如:如果你正在创build一个recursive函数来重用相同的typeglob,当你试图closures文件句柄时,你会得到一些警告,除非你创build一个基于时间限制的基于包的glob。 词法variables的作用范围是它们被定义的区块,而typeglob范围则是它所定义的完整的包装。

恢复:

如果你想留在typeglob文件句柄中,请确保创build一个基于时间限制的基于包的glob:

 ... local *FH; open FH, '<', $filepath or die(sprintf('Could not open %s: %s', $filepath, $!)); ... 

否则,使用一个词法variables

 ... open my $fh, '<', $filepath or die(sprintf('Could not open %s: %s', $filepath, $!)); ...