问题描述
open 函数的文档 显示了 open() 的语法
为:
- 打开文件句柄,EXPR
- 打开文件句柄、模式、表达式
- 打开文件句柄、模式、表达式、列表
- 打开文件句柄、模式、参考
- 打开文件句柄
在示例中,它们有一些地方使用普通的 $-prefixed 变量作为文件句柄:
Down in the examples they have places where a normal $-prefixed variable is used for the file handle:
open(my $fh, "<", "input.txt")
还有使用裸字的例子:
open(FOO, "|tr '[a-z]' '[A-Z]'");
一个问题是,在每种情况下,我使用 __ 作为文件句柄"中的每种样式的名称是什么?另一个是,为什么他们开始在文档中为 open()
使用裸词?似乎是后来的使用都不涉及正常的文件名open()
s.在这些情况下,以 $ 为前缀的形式是否不可接受?
One question is what is the name of each style as in "I am using __ for a filehandle" in each case? The other is, why did they start using bare words for open()
in the documentation? It appears to be the later uses all don't involve normal filename open()
s. Is the $-prefixed form not acceptable in those instances?
推荐答案
从本质上讲,裸字形式只是为了向后兼容的历史遗留问题.在新代码中使用词法变量几乎总是正确的做法.
The bareword form is, essentially, just historical legacy for backward compatibility. Using a lexical variable is pretty much always The Right Thing To Do in new code.
→ 顺便说一句,$x
是一个词法标量变量,其中 FOO
就像你说的,叫做裸字
→ incidentally, $x
is a lexical scalar variable, where FOO
is, as you said, called a bareword
细节/题外话
只是为了完整性,正如@Joe_Z 在评论中指出的那样,词法文件句柄对象是相对较新的",作为 Perl 5.005 和 5.6 之间相当重要的重写的一部分(它们甚至在那个版本中获得了整个数量级数字……).
Just for completeness, as @Joe_Z pointed out in the comments, the lexical filehandle objects are "relatively new," as a part of the rather major rewrite between Perl 5.005 and 5.6 (they even gained whole orders of magnitude in that version number…).
但是,从技术上讲,裸字 FOO
(或例如 STDIN
)在单独的命名空间中被解释为仅用于文件句柄.由于文件句柄命名空间没有符号(如 $ @ % &
),因此只有两种方法可以引用该命名空间中的文件句柄:
However, technically, the bareword FOO
(or, e.g. STDIN
) is interpreted in a separate namespace just for filehandles. Since there isn't a sigil (like $ @ % &
) for the filehandle namespace, there are only two ways to reference a filehandle in that namespace:
- 您可以在某些函数的间接对象槽中引用它,例如
print
,由于历史原因,它会(在幕后)推断出裸字必须引用文件句柄; - 您可以使用 typeglob,例如
*FOO
,它指的是任何命名空间中碰巧绑定到符号FOO
的任何内容.
- You can refer to it in the indirect-object slot of certain functions, like
print
, who will (behind the scenes) infer that a bareword must refer to a filehandle, for historical reasons; - You can use a typeglob, like
*FOO
, which refers to "anything in any namespace which happens to be bound to the symbolFOO
.
请注意,在某些语言中,例如 C 或 Scheme,单个符号没有类型符号,因此所有符号只能以一种方式绑定(例如,不能有名为 printf
的变量和在 C 中名为 printf
的函数......通常),而在 Perl 或(例如)Common Lisp 中,相同的符号 foo
可以绑定到许多不同的东西;区别在于,在大多数情况下,Perl 实际上要求您使用 sigil 来消除您的意思是哪个 foo
"的歧义.$foo
, @foo
= @foo[ $x .. $y]
, $foo[ $n ]
, %foo
= @foo{ $k1, $k2 }
= $foo{ $k }
, &foo
之类的.
Note that in some languages, like C or Scheme, a single symbol has no type sigils, and so all symbols can be bound only in one way (e.g. one cannot have a variable named printf
and a function named printf
in C … generally), whereas in Perl or (e.g.) Common Lisp, the same symbol foo
can be bound to many different things; the distinction is that Perl actually requires you to use sigils to disambiguate "which foo
you mean" in most contexts. $foo
, @foo
= @foo[ $x .. $y]
, $foo[ $n ]
, %foo
= @foo{ $k1, $k2 }
= $foo{ $k }
, &foo
and the like.
但是,通过使用裸字作为文件句柄,您会失去一些能力:
By using barewords as filehandles, though, you lose some abilities:
重要的是,为了在本地或词法上(而不是全局)绑定它们,您需要绑定每个命名空间中的每个符号,因为没有可用的符号.因此,my $foo
和 my @foo
可以存在于两个不同的暂存器(范围)中,其中一个可能比另一个更长寿;但是 my *foo
将包括这两个,以及文件句柄 foo
(以及可能其他晦涩的角落情况,例如 format
说明符,虽然我不会发誓).
Significantly, in order to bind them locally or lexically (instead of globally), you need to bind every symbol in every namespace, because there is no sigil available. Thus, my $foo
and my @foo
can live in two different scratchpads (scopes), where perhaps one outlives the other; but my *foo
would include both of these, as well as the filehandle foo
(and potentially other obscure corner-cases, like format
specifiers, although I wouldn't swear to it).
将裸字样式的文件句柄传递给函数等也非常困难.
It's also immensely difficult to pass a bareword-style filehandle into a function, and the like.
基本上,裸字继承了全局作用域的所有缺点,并且没有词法变量的任何优点.
Basically, barewords inherit all of the downsides of global scope and have none of the advantages of lexical variables.
perldoc perldata
有一个关于 Typeglobs 和文件句柄 的很好的部分,它可能也更清楚地解释了这些事情.我手边没有我的副本,但我相信 Camel 也会详细介绍这个主题.
perldoc perldata
has a nice section on Typeglobs and Filehandles which probably explains these things a bit more clearly, as well. I don't have my copy handy, but I believe the Camel goes into more detail on the subject, as well.
这篇关于为什么 Perl open() 文档使用两种不同的 FILEHANDLE 样式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!