【问题标题】:Assign STDIN to variable in strict mode在严格模式下将 STDIN 分配给变量
【发布时间】:2015-05-23 21:38:38
【问题描述】:

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

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

如何使用use strict; 获得同等解决方案?


到目前为止,我已经尝试过:${STDIN}$STDIN\$STDIN&lt;STDIN&gt;\STDIN,并且我知道最后两个运算符(&lt;&gt;\)有与我想在这里使用的含义不同。

STDIN 到底是什么变量?它是否被视为标量?

【问题讨论】:

  • 它是一个文件系统全局...试试*STDIN
  • @dgw:谢谢,这就是我要找的接线员。我在哪里可以找到有关该运营商的一些文档? perlop 似乎不是正确的地方。
  • 尝试perldoc perldata 并搜索/Typeglobs and Filehandles/ perldoc.perl.org/perldata.html#Typeglobs-and-Filehandles>。

标签: perl strict


【解决方案1】:
my $stdin_h = \*STDIN;

提供最少的惊喜。那是一个全局引用。

另见perldoc perlrefTypeglobs and Filehandles in perldata

typeglob 的另一个用途是将文件句柄传递给函数或创建新的文件句柄。如果您需要使用 typeglob 来保存文件句柄,请这样做:

$fh = *STDOUT;

或者作为一个真正的参考,像这样:

$fh = \*STDOUT;

STDIN 是一个裸词。当函数的参数需要文件句柄时,它等效于上述\*STDIN 之一,但其余时间等效于"STDIN"use strict 'refs'; 会抛出错误)。

我链接到的 Perl 文档解释了所涉及的各种数据类型之间的差异,但 DavidW 的简短摘要很有用:

*STDIN 是一个类型 glob。这与 Perl 如何在其符号表中存储信息有关。 Perl 在其符号表中为特定名称创建一个条目,然后为具有这些名称的子例程、文件句柄、散列、数组和标量创建散列条目。您可以使用 * sigil 引用此符号表条目,它称为类型 glob。问题是文件句柄没有标记,因此您必须使用 glob 类型引用它们。当你open FH ... 时,FH 是一个文件句柄。当你使用open my $fh ... 时,$fh 是一个类型 glob ref。

【讨论】:

  • 您能否解释一下我在问题中发布的简短示例中分配简单的*STDIN 和引用\*STDIN 之间的区别?使用$var = *STDIN有什么副作用吗?
  • *STDIN 是一个 type glob。这与 Perl 如何在其符号表中存储信息有关。 Perl 在其符号表中为特定名称创建一个条目,然后为具有这些名称的子例程、文件句柄、散列、数组和标量创建散列条目。您可以使用 * sigil 引用此符号表条目,它称为类型 glob。问题是文件句柄没有标记,因此您必须使用 glob 类型引用它们。当你open FH... 时,FH 是一个文件句柄。当你使用open my $fh... `$fh 是一个类型 glob ref.
  • @DavidW。我将在答案中插入您的评论。如果您不喜欢,请随意编辑。
【解决方案2】:

Sinan Ünür 有一种将文件句柄实际获取到变量中的方法,并且在 Perl 文档中有所提及。

然而,它涉及到深奥的 Perl 奥秘,这可能会让许多不熟悉这些秘密的开发人员感到困惑。你必须知道查看 perldata 并查看 last section,这就是你弄清楚 Typeglob 是什么的时候。

还有另一种不那么神秘且更容易理解的方式:

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

由于fdopenIO::File 的一个方法,你知道你可以在IO::File Perldoc 中找到有关它的信息。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-08-20
    • 2015-10-11
    • 2013-07-31
    • 1970-01-01
    • 1970-01-01
    • 2013-12-06
    • 2018-10-02
    • 1970-01-01
    相关资源
    最近更新 更多