使用no strict
时,以下代码完全符合预期:
my $file = STDIN;
while (<$file>) {
print "$_\n";
}
使用use strict;
怎么会是一个平等的解决方案?
到目前为止我已尝试过:${STDIN}
,$STDIN
,\$STDIN
,<STDIN>
和\STDIN
,我知道最后两个运营商(<>
和\
)的含义与我在此处使用的含义不同。
无论如何,STDIN
是什么类型的变量?它被认为是标量吗?
答案 0 :(得分:8)
my $stdin_h = \*STDIN;
提供最少的惊喜。那是一个全球性的。
另请参阅perldoc perlref和Typeglobs and Filehandles in perldata:
typeglobs的另一个用途是将文件句柄传递给函数或创建新的文件句柄。如果您需要使用typeglob来保存文件句柄,请按以下方式执行:
$fh = *STDOUT;
或者作为真正的参考,像这样:
$fh = \*STDOUT;
STDIN
是一个简单的词。当一个函数的参数期望一个文件句柄时,它等同于上面的\*STDIN
之一,但它在剩下的时间里相当于"STDIN"
(use strict 'refs';
抛出一个错误)
我链接的Perl文档解释了所涉及的各种数据类型之间的差异,但DavidW的简短摘要非常有用:
*STDIN
是一个类型的glob。这与Perl如何在其符号表中存储信息有关。 Perl在其符号表中为特定名称创建一个条目,然后为子例程,文件句柄,哈希,数组和带有这些名称的标量创建哈希条目。您可以使用*
sigil引用此符号表条目,它称为类型glob。问题是文件句柄没有sigil,所以你必须用glob类型引用它们。当您open FH ...
时,FH
是文件句柄。当您使用open my $fh ...
时,$fh
是类型glob ref。
答案 1 :(得分:1)
Sinan Ünür有一种方法可以将文件句柄实际变为变量,并在Perl文档中提到。
但是,它涉及深色的Perl谜团,对于许多不熟悉这些秘密的开发人员来说可能会让人感到困惑。你必须知道要查看perldata并查看last section,这就是你弄清楚Typeglobs是什么。
还有另一种不那么神秘且易于理解的方式:
use strict;
use warnings;
use feature qw(say);
use autodie; # Doesn't work. You need to verify
use IO::File;
...
my $file = IO::File->new;
$file->fdopen( fileno( STDIN ), 'r')
or die qq(<STDIN> is not opened.);
while ( my $entry = <$file> ) {
chomp $entry;
say qw(The entry is "$entry");
}
好吧,这也不是很清楚,但它确实有一个优势,你知道在哪里寻找文档。 fileno
是一个函数,因此很容易查找(返回文件句柄的文件描述符,如果文件句柄未打开则返回未定义。)。
由于fdopen
是IO::File的方法,因此您知道可以在IO::File
Perldoc中找到有关该方法的信息。
好吧,我说谎了,fdopen
的文档实际上在IO::Handle Perldoc中。但是,IO::File
Perldoc确实说它从IO::Handle
继承了它的方法。一旦你确定要查看IO::Handle
,就会在synopsis中看到这个代码的示例。