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

gcb*_*son 2 perl

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

%foo = %bar
Run Code Online (Sandbox Code Playgroud)

不用担心弄乱价值%bar.

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

*FOO = *BAR
Run Code Online (Sandbox Code Playgroud)

我不仅使得<FOO>做同样的事情<BAR>,我已经改变$FOO,@FOO%FOO也.

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

ike*_*ami 7

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

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

如你所述,*FOO = *BAR;复制glob就像%foo = %bar;复制哈希一样.所以相同的逻辑适用于文件句柄全局.

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

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

 *FOO = *BAR{IO};
Run Code Online (Sandbox Code Playgroud)

甲水珠(例如*FOO)是一个关联数组如哈希,用一组固定的键包括SCALAR,ARRAY,...和IO.分配对glob的引用(例如返回*BAR{IO}的引用)将自动为glob的正确槽指定引用.

但你为什么搞乱球?你会怎么做

*foo = \$bar;
Run Code Online (Sandbox Code Playgroud)

要么

*foo = *bar{SCALAR};
Run Code Online (Sandbox Code Playgroud)

复制一个字符串?不,那么为什么要这样做才能复制文件句柄.喜欢弦乐,你应该使用

 $foo = $bar;
Run Code Online (Sandbox Code Playgroud)

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

 open(my $BAR, ...) or die $!;
 my $FOO = $BAR;
Run Code Online (Sandbox Code Playgroud)

要么

 my $FOO = \*STDOUT;
Run Code Online (Sandbox Code Playgroud)

然后$FOO按照您的意愿使用FOO.

while (<FOO>)    =>   while (<$FOO>)
print FOO ...;   =>   print $FOO ...;
func(\*FOO);     =>   func($FOO);
Run Code Online (Sandbox Code Playgroud)


der*_*ert 6

好吧,你可以这样做:

*FOO = *BAR{IO}
Run Code Online (Sandbox Code Playgroud)

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

open my $foo, '<', 'filename';
my $line = <$foo>;
# ?
Run Code Online (Sandbox Code Playgroud)

然后,当然,你可以像任何其他标量一样复制它们$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
Run Code Online (Sandbox Code Playgroud)