有人说我们应该使用词法文件句柄而不是类型字符串,如下所示:
open $fh, $filename;
但大多数Perl书籍,包括The Llama Book,都使用了typeglob,如下所示:
open LOGFILE, $filename;
那有什么区别?哪一个被认为是更好的做法?
答案 0 :(得分:22)
最早版本的Llama Book是从1993年开始的,之前词汇文件是Perl语言的一部分。由于各种原因,词法文件句柄是更好的做法。 typeglobs最重要的缺点是
它们总是在全球范围内,这可能导致像这样的阴险错误:
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;
它们更难传递给子程序而不是词法文件句柄
package package1; sub log_time { # print timestamp to filehandle my ($fh) = @_; print $fh scalar localtime, "\n"; } package package2; open GLOB, '>', 'log1'; open $lexical, '>', 'log2'; package1::log_time($lexical); # works as expected package1::log_time(GLOB); # doesn't work package1::log_time('GLOB'); # doesn't work package1::log_time(*GLOB); # works package1::log_time(package2::GLOB); # works package1::log_time('package2::GLOB'); # works
另请参阅:Why is three-argument open calls with autovivified filehandles a Perl best practice?
答案 1 :(得分:14)
当使用词法变量时,文件句柄具有这些变量的范围,并在您离开该范围时自动关闭:
{
open my $fh, '<', 'file' or die $!;
# ...
# the fh is closed upon leaving the scope
}
所以你不要创建永久的全局变量。
答案 2 :(得分:8)
词法文件句柄可以作为参数轻松传递,文件句柄不能。 Typeglobs可以(或者至少可以引用它们),但这有点混乱。考虑坚持使用词汇变量,并确保首先声明它们,这样你才能知道它们是真正的词汇,而不是本地或全局的。即。
my $fh;
open $fh, $filename;
另请考虑使用IO::Handle
或IO::File
作为选项。曾经是FileHandle
,但ysth通知FileHandle
现在只是依次使用'IO :: Handle',这对我来说是5.6以来的新闻,但还有很多东西需要学习这里。 : - )
另外,不要忘记use strict
: - )
答案 3 :(得分:1)
建议不要使用typeglob文件句柄,因为如果不注意,可能会导致一些问题。例如:如果您正在创建一个重用同一类型的递归函数,当您尝试关闭文件句柄时,除非您创建一个基于时间限制的基于包的glob,否则会收到一些警告。词法变量的范围限定在定义它们的块中,而typeglob范围适用于定义它的完整包。
要恢复:
如果你想留下typeglob文件句柄,请确保创建一个基于时间限制的基于包的glob:
...
local *FH;
open FH, '<', $filepath or die(sprintf('Could not open %s: %s', $filepath, $!));
...
否则,使用词汇变量
...
open my $fh, '<', $filepath or die(sprintf('Could not open %s: %s', $filepath, $!));
...