在严格模式下将STDIN分配给变量

时间:2015-03-20 13:05:26

标签: perl strict

使用no strict时,以下代码完全符合预期:

my $file = STDIN;
while (<$file>) {
    print "$_\n";
}

使用use strict;怎么会是一个平等的解决方案?


到目前为止我已尝试过:${STDIN}$STDIN\$STDIN<STDIN>\STDIN,我知道最后两个运营商(<>\)的含义与我在此处使用的含义不同。

无论如何,STDIN是什么类型的变量?它被认为是标量吗?

2 个答案:

答案 0 :(得分:8)

my $stdin_h = \*STDIN;

提供最少的惊喜。那是一个全球性的。

另请参阅perldoc perlrefTypeglobs 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是一个函数,因此很容易查找(返回文件句柄的文件描述符,如果文件句柄未打开则返回未定义。)。

由于fdopenIO::File的方法,因此您知道可以在IO::File Perldoc中找到有关该方法的信息。

好吧,我说谎了,fdopen的文档实际上在IO::Handle Perldoc中。但是,IO::File Perldoc确实说它从IO::Handle继承了它的方法。一旦你确定要查看IO::Handle,就会在synopsis中看到这个代码的示例。