我已经遇到两种不同的语法来读取STDIN的输入,但是我无法弄清楚两者之间是否存在差异。
我介绍的第一种方法是:
$IN = Bio::SeqIO->new(-fh => *STDIN{IO}, '-format' => 'fasta', '-alphabet' => $moltype);
稍后在询问有关BioPerl IRC的一些问题后,我被告知这样写:
$IN = Bio::SeqIO->new(-fh => \*STDIN, '-format' => 'fasta', '-alphabet' => $moltype);
答案 0 :(得分:3)
*STDIN{IO}
将返回对IO对象的引用。
$ perl -MDevel::Peek -e'Dump(*STDIN{IO})'
SV = IV(0x166b988) at 0x166b998
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x1688fe0
SV = PVIO(0x168b5f0) at 0x1688fe0
...
\*STDIN
将返回对包含IO对象的glob的引用。
$ perl -MDevel::Peek -e'Dump(\*STDIN)'
SV = IV(0xf5f988) at 0xf5f998
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0xf7cfc8
SV = PVGV(0xf749b0) at 0xf7cfc8
...
所有Perl内置函数都可以处理 [1] ,但后者应该得到XS模块 [2] 的更好支持,因为它是open $fh, ...
所放置的标量。
$ perl -MDevel::Peek -e'open(my $fh, "<", "/dev/null") or die; Dump($fh);'
SV = IV(0x144a518) at 0x144a528
REFCNT = 1
FLAGS = (PADMY,ROK)
RV = 0x142c998
SV = PVGV(0x1485c80) at 0x142c998
...
*STDIN
)或符号名称作为字符串(例如"STDIN"
)。答案 1 :(得分:1)
出于所有意图和目的,它们是等同的。您会更频繁地看到\*STDIN
表单,而我更喜欢*STDIN{IO}
。
表单\*STDIN
创建对“typeglob”的引用。 glob是Perl的包符号表中的一个条目。每个glob包含各种类型的引用 - glob *foo
有一个哈希%foo
,可以*foo{HASH}
访问,一个数组@foo
在*foo{ARRAY}
,一个标量,格式,子例程和IO事物:*foo{IO}
。如果不存在相应的变量,则可能未定义任何槽。
“IO thingy”将是任何当前Perl上->isa('IO::Handle')
的对象。这是一个完整的对象与方法等。所以我们可以做
my $fh = *STDOUT{IO};
$fh->say("foo"); # you may need to "use IO::File" to actually load the methods
但为方便起见,STDOUT->say("foo")
(裸字)和(\*STDOUT)->say("foo")
(glob引用)也可以使用,但它们的类型不同。