在严格模式下将标准输入分配给变量

5
以下代码在使用no strict时运行得相当顺利:
my $file = STDIN;
while (<$file>) {
    print "$_\n";
}

使用use strict;,如何实现相同的解决方案?
到目前为止,我尝试了:${STDIN}$STDIN\$STDIN<STDIN>\STDIN。我知道最后两个运算符(<>\)在这里有不同的含义。 STDIN是什么样的变量?它被认为是标量吗?

5
这是一个文件系统的通配符,建议尝试使用 *STDIN - dgw
@dgw:谢谢,那正是我在寻找的运算符。我在哪里可以找到有关该运算符的文档?perlop似乎不是正确的地方。 - Manuel Faux
2
尝试运行 perldoc perldata 并搜索 /Typeglobs and Filehandles/ http://perldoc.perl.org/perldata.html#Typeglobs-and-Filehandles。 - shawnhcorey
2个回答

11
my $stdin_h = \*STDIN;

提供最少惊喜。 这是全局引用。

另请参见perldoc perlrefperldata中的类型全局引用和文件句柄

Another use for typeglobs is to pass filehandles into a function or to create new filehandles. If you need to use a typeglob to save away a filehandle, do it this way:

$fh = *STDOUT;

or perhaps as a real reference, like this:

$fh = \*STDOUT;
STDIN是一个裸字。当作为函数参数时,它相当于上面的*STDIN之一,但在其他时间(对此use strict 'refs';会抛出错误)它相当于"STDIN"。Perl文档中解释了涉及的各种数据类型之间的区别,但DavidW的简要摘要也很有用:*STDIN是一个类型glob。这与Perl如何在其符号表中存储信息有关。 Perl为特定名称创建一个条目,然后使用这些名称为子例程、文件句柄、哈希、数组和标量创建哈希条目。您可以使用* sigil 引用此符号表条目,称为类型glob。问题是,文件句柄没有 sigil,因此必须使用类型 glob 引用它们。当你 open FH ... 时,FH 是文件句柄。当你使用 open my $fh ... 时,$fh 是类型glob引用。

请问您能否解释一下在我提出的问题中,将简单的*STDIN和引用的\*STDIN分配给变量之间的区别?当使用$var = *STDIN时是否会产生任何副作用? - Manuel Faux
3
*STDIN 是一个类型全局变量。这与 Perl 如何在其符号表中存储信息有关。Perl 为特定名称在其符号表中创建一个条目,然后使用这些名称创建子例程、文件句柄、哈希、数组和标量的哈希条目。您可以使用 * 符号引用此符号表条目,并且称之为类型全局变量。问题在于文件句柄没有 sigil,因此您必须使用类型全局变量来引用它们。当您使用 open FH... 时,FH 是一个文件句柄。当您使用 open my $fh... 时,$fh 是一个类型全局变量的引用。 - David W.
1
@DavidW。我将在答案中插入您的评论。如果您不喜欢,可以随意编辑。 - Sinan Ünür

2

Sinan Ünür提供了一种方法,可以将文件句柄实际存储到一个变量中,并在Perl文档中提到。

然而,这涉及到深奥的Perl秘密,可能会让许多开发人员感到困惑,尤其是那些不熟悉这些秘密的人。你必须知道去查看perldata,并查看最后一节Typeglobs和Filehandles,如果你弄清楚了Typeglobs是什么的话。

还有另一种 less mysterious and easier to understand 的方法:

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中看到这个非常代码的示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接