在严格模式下将 STDIN 分配给变量
Assign STDIN to variable in strict mode
以下代码在使用 no strict
时完全符合预期:
my $file = STDIN;
while (<$file>) {
print "$_\n";
}
如何使用 use strict;
得到一个相等的解决方案?
到目前为止我已经尝试过:${STDIN}
、$STDIN
、$STDIN
、<STDIN>
和 \STDIN
,我知道最后一个两个运算符(<>
和 \
)的含义与我想在这里使用的不同。
STDIN
到底是个什么样的变量?它被认为是标量吗?
my $stdin_h = \*STDIN;
提供的惊喜最少。那是一个 globref.
另见 perldoc perlref and Typeglobs and Filehandles in perldata:
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
之一,但在其余时间等效于 "STDIN"
(use strict 'refs';
会引发错误) .
我链接到的 Perl 文档解释了所涉及的各种数据类型之间的差异,但 DavidW 的简短摘要很有用:
*STDIN
is a type glob. This has to do with how Perl stores info in its symbol table. Perl creates an entry in it's symbol table for a particular name, and then creates hash entries for subroutines, file handles, hashes, arrays, and scalars with those names. You can reference this symbol table entry with a *
sigil and it's called a type glob. The problem is that there is no sigil for file handles, so you have to refer to them with the type glob. When you open FH ...
, FH
is a file handle. When you use open my $fh ...
, $fh
is a type glob ref.
有一种将文件句柄实际放入变量的方法,在 Perl 文档中有所提及。
然而,它涉及深奥的 Perl 奥秘,这可能会让许多不熟悉这些秘密的开发人员感到困惑。你必须知道查看 perldata and look in the very 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");
}
好吧,这也不完全 crystal 清楚,但它确实有一个优点,即您知道在哪里可以找到文档。 fileno
是一个函数,因此很容易查找(Returns 文件句柄的文件描述符,如果文件句柄未打开则为未定义。)。
并且由于 fdopen
是 IO::File 的一个方法,您知道您可以在 IO::File
Perldoc 中找到相关信息。
好吧,我撒谎了,fdopen
的文档实际上在 IO::Handle Perldoc. But, the IO::File
Perldoc does say that it inherits its methods from IO::Handle
. Once you do figure out to look in IO::Handle
, you see an example of this very code right in the synopsis.
以下代码在使用 no strict
时完全符合预期:
my $file = STDIN;
while (<$file>) {
print "$_\n";
}
如何使用 use strict;
得到一个相等的解决方案?
到目前为止我已经尝试过:${STDIN}
、$STDIN
、$STDIN
、<STDIN>
和 \STDIN
,我知道最后一个两个运算符(<>
和 \
)的含义与我想在这里使用的不同。
STDIN
到底是个什么样的变量?它被认为是标量吗?
my $stdin_h = \*STDIN;
提供的惊喜最少。那是一个 globref.
另见 perldoc perlref and Typeglobs and Filehandles in perldata:
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
之一,但在其余时间等效于 "STDIN"
(use strict 'refs';
会引发错误) .
我链接到的 Perl 文档解释了所涉及的各种数据类型之间的差异,但 DavidW 的简短摘要很有用:
*STDIN
is a type glob. This has to do with how Perl stores info in its symbol table. Perl creates an entry in it's symbol table for a particular name, and then creates hash entries for subroutines, file handles, hashes, arrays, and scalars with those names. You can reference this symbol table entry with a*
sigil and it's called a type glob. The problem is that there is no sigil for file handles, so you have to refer to them with the type glob. When youopen FH ...
,FH
is a file handle. When you useopen my $fh ...
,$fh
is a type glob ref.
然而,它涉及深奥的 Perl 奥秘,这可能会让许多不熟悉这些秘密的开发人员感到困惑。你必须知道查看 perldata and look in the very 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");
}
好吧,这也不完全 crystal 清楚,但它确实有一个优点,即您知道在哪里可以找到文档。 fileno
是一个函数,因此很容易查找(Returns 文件句柄的文件描述符,如果文件句柄未打开则为未定义。)。
并且由于 fdopen
是 IO::File 的一个方法,您知道您可以在 IO::File
Perldoc 中找到相关信息。
好吧,我撒谎了,fdopen
的文档实际上在 IO::Handle Perldoc. But, the IO::File
Perldoc does say that it inherits its methods from IO::Handle
. Once you do figure out to look in IO::Handle
, you see an example of this very code right in the synopsis.