8

open 函数的文档显示如下语法open()

  • 打开文件句柄,EXPR
  • 打开文件句柄,模式,EXPR
  • 打开文件句柄、模式、表达式、列表
  • 打开文件句柄、模式、参考
  • 打开文件句柄

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

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

以及使用裸词的示例:

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

一个问题是在每种情况下,每种样式的名称是什么,例如“我正在使用__作为文件句柄”?另一个是,为什么他们开始在文档中使用裸词for open()?看来以后的使用都不涉及正常open()的 filename 。在这些情况下是否不接受以 $ 为前缀的形式?

4

2 回答 2

22

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

→ 顺便说一句,$x是一个词法标量变量FOO正如你所说,它被称为裸词

细节/题外话

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

然而,从技术上讲,bareword FOO(或,例如STDIN)在一个单独的命名空间中被解释为文件句柄。由于文件句柄命名空间没有符号(如$ @ % &),因此只有两种方法可以引用该命名空间中的文件句柄:

  • 您可以在某些函数的间接对象槽中引用它,例如print,由于历史原因,谁会(在幕后)推断裸字必须引用文件句柄;
  • 你可以使用 typeglob,比如*FOO,它指的是“任何命名空间中碰巧绑定到符号FOO.

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

但是,通过使用裸词作为文件句柄,您会失去一些能力:

重要的是,为了在本地或词法上(而不是全局)绑定它们,您需要绑定每个命名空间中的每个符号,因为没有可用的印记。因此,my $foo并且my @foo可以存在于两个不同的暂存器(示波器)中,其中一个可能比另一个寿命长;但my *foo会包括这两个,以及文件句柄foo(以及可能的其他晦涩的极端情况,如format说明符,尽管我不会发誓)。

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

基本上,barewords 继承了全局作用域的所有缺点,并且没有词法变量的优点。

perldoc perldata在Typeglobs 和 Filehandles上有一个很好的部分,它可能也更清楚地解释了这些事情。我手头没有我的副本,但我相信骆驼也会更详细地讨论这个主题。

于 2013-06-29T02:42:24.167 回答
2

正如 BPRocock 所说,如今my $x是首选,而FOO被认为已过时,因为FOO它是一种全局变量,因此它可能与其他地方使用的名称冲突。$x鼓励还有另一个原因:$xclose在范围结束时自动编辑。

于 2013-06-29T16:13:26.690 回答