为什么Perl open()文档使用两种不同的FILEHANDLE样式?

时间:2013-06-29 02:38:04

标签: perl filehandle bareword

documentation for the open functionopen()的语法显示为:

  • 打开FILEHANDLE,EXPR
  • 打开FILEHANDLE,MODE,EXPR
  • 打开FILEHANDLE,MODE,EXPR,LIST
  • 打开FILEHANDLE,MODE,REFERENCE
  • 打开FILEHANDLE

在示例中,他们有一个普通的$ -prefixed变量用于文件句柄的地方:

open(my $fh, "<", "input.txt")

以及使用裸字的示例:

open(FOO, "|tr '[a-z]' '[A-Z]'");

一个问题是每个样式的名称是什么,在每种情况下“我正在使用 _ _作为文件句柄”?另一个是,他们为什么开始在文档中使用{/ 1}}的简单字?它似乎是后来的用途都不涉及正常的文件名open()。在这些情况下,$ -prefixed表单是不可接受的吗?

2 个答案:

答案 0 :(得分:21)

裸字形式本质上只是向后兼容的历史遗产。在新代码中使用词法变量几乎总是正确的事情。

→顺便说一下,$x是一个词汇标量变量,其中FOO就像你所说的那样叫做一个裸字

<强>详情/题外话

为了完整性,正如@Joe_Z在评论中指出的那样,词汇文件句柄对象是“相对较新的”,作为Perl 5.005和5.6之间相当重要的重写的一部分(他们甚至在该版本中获得了整个数量级)号...)。

但是,从技术上讲,裸字FOO(或者,例如STDIN)仅在文件句柄的单独命名空间中进行解释。由于文件句柄命名空间没有sigil(如$ @ % &),因此只有两种方法可以引用该命名空间中的文件句柄:

  • 您可以在某些功能的间接对象插槽中引用它,例如print,由于历史原因,他将(在幕后)推断出一个裸字必须引用文件句柄;
  • 您可以使用类似{4}的typeglob,它指的是“任何名称空间中碰巧绑定到符号*FOO的任何内容。

请注意,在某些语言中,如C或Scheme,单个符号没有类型符号,因此所有符号只能以一种方式绑定(例如,一个不能有名为FOO的变量和一个名为的函数通常在C语言中printf,而在Perl或(例如)Common Lisp中,相同的符号printf可以绑定到许多不同的东西;区别在于Perl实际上要求您使用符号来消除“大多数情况下foo你的意思”。 foo$foo = @foo@foo[ $x .. $y]$foo[ $n ] = %foo = @foo{ $k1, $k2 }$foo{ $k }

通过使用裸字作为文件句柄,你会失去一些能力:

值得注意的是,为了在本地或词汇上(而不是全局)绑定它们,您需要在每个命名空间中绑定每个符号,因为没有可用的符号。因此,&foomy $foo可以存在于两个不同的刮板(范围)中,其中一个可能比另一个更长;但是my @foo会包含这两个,以及文件句柄my *foo(以及可能还有其他模糊的角落情况,例如foo说明符,尽管我不会发誓。)< / p>

将一个裸字样式的文件句柄传递给函数等也非常困难。

基本上,裸字继承了全局范围的所有缺点,并且没有词汇变量的优点。

format Typeglobs和Filehandles 上有一个很好的部分,它可能会更清楚地解释这些事情。我没有方便的副本,但我相信Camel也会详细介绍这个主题。

答案 1 :(得分:2)

正如BPRocock所说,my $x这些天是首选,而FOO被认为是过时的,因为FOO是一种全局变量,因此它可能与另一个地方使用的名称冲突。鼓励$x的另一个原因是:$x会在范围的最后自动close