为什么文件句柄没有专用的类型?

时间:2013-06-06 16:33:09

标签: perl

哈希和标量位于不同的命名空间中。所以我可以这样做:

%foo = %bar

无需担心会弄乱%bar的价值。

为什么不同的逻辑适用于文件句柄?如果我这样做:

*FOO = *BAR

我不仅让<FOO>做与<BAR>相同的事情,我还改变了$FOO@FOO%FOO

这样的方式只是因为Perl是第一次写的,而且它是根深蒂固的?因为还没有剩下的非字母数字前缀字符?或者以这种方式工作的原因是什么?

3 个答案:

答案 0 :(得分:7)

  

为什么不同的逻辑适用于文件句柄?

首先*BAR不是文件句柄;它是一个水珠。 “Glob”是“type glob”或“typeglob”的缩写。 Globs是符号表的组成部分。

正如您所说,*FOO = *BAR;确实复制了glob,就像%foo = %bar;复制哈希一样。所以相同的逻辑适用于 filehandles globs。

没有办法专门引用Perl中的文件句柄。它总是通过glob,引用或对glob的引用间接完成。

如果要将文件句柄从一个glob复制到另一个glob,可以使用以下命令:

 *FOO = *BAR{IO};

glob(例如*FOO)是一个像哈希一样的关联数组,包含一组固定的键,包括SCALARARRAY,...和IO。分配对glob的引用(例如*BAR{IO}返回的引用)将自动分配对glob的正确槽的引用。

但你为什么要搞乱球?你能做吗

*foo = \$bar;

*foo = *bar{SCALAR};

复制一个字符串?不,那么为什么要这样做才能复制文件句柄。就像字符串一样,你应该使用

 $foo = $bar;

您遇到困难的根本原因是因为您使用的技术已经淘汰了13年(6个主要版本)。你不应该使用全局变量;你应该使用正确范围的词汇。

 open(my $BAR, ...) or die $!;
 my $FOO = $BAR;

 my $FOO = \*STDOUT;

然后使用$FOO,就像使用FOO一样。

while (<FOO>)    =>   while (<$FOO>)
print FOO ...;   =>   print $FOO ...;
func(\*FOO);     =>   func($FOO);

答案 1 :(得分:6)

嗯,你可以这样做:

*FOO = *BAR{IO}

但是,老实说,使用裸字文件句柄(看起来像FOO)最好留下来。它是一个历史文物,在Perl 5.6(多年前)上已经过时了。相反,您应该将文件句柄放在标量中:

open my $foo, '<', 'filename';
my $line = <$foo>;
# ⋮

然后,当然,您可以像任何其他标量$bar = $foo一样复制它们。

此外,您通常希望避免两个具有相同名称的变量,因为它会让人感到困惑。

my @a = (1, 2, 3);
my $a = 4;
my %a = (5 => 6, 7 => 8);

say $a, $a[0], $a{5}; # the scalar, the array, the hash (in that order)
say @a{5,7};          # the hash

答案 2 :(得分:0)

查看Perldata下的文档(参见Typeglobs和Filehandles部分)。第一部分是:

Perl使用名为typeglob的内部类型来保存整个符号表条目。 typeglob的类型前缀是*,因为它代表所有类型。这曾经是通过引用将数组和哈希值传递给函数的首选方法,但现在我们有了真正的引用,这很少需要。