代码
$ cat test1
hello
i am
lazer
nananana
$ cat 1.pl
use strict;
use warnings;
my @fh;
open $fh[0], '<', 'test1', or die $!;
my @res1 = <$fh[0]>; # Way1: why does this not work as expected?
print @res1."\n";
my $fh2 = $fh[0];
my @res2 = <$fh2>; # Way2: this works!
print @res2."\n";
生成
$ perl 1.pl
1
5
$
我不确定Way1
在Way2
执行时{{1}}无效的原因。这两种方法不一样吗?这里发生了什么?
答案 0 :(得分:14)
由于&lt;&gt;的双重性质运算符(即它是glob还是readline?),规则就是表现为readline,你只能在括号内有一个单词或一个简单的标量。因此,您必须将数组元素分配给一个简单的标量(如示例所示),或者直接使用readline函数。
答案 1 :(得分:14)
因为来自perlop:
如果尖括号内的内容既不是文件句柄也不是包含文件句柄名称,typeglob或typeglob引用的简单标量变量,则它被解释为要进行全局化的文件名模式,以及文件名列表或下一个文件名在列表中返回,具体取决于上下文。这种区别仅仅是出于句法原因而确定的。这意味着
<$x>
始终是来自间接句柄的readline(),但<$hash{key}>
始终是glob()。
您可以将<>
运算符拼写为readline,以避免出现此魔法问题。
答案 2 :(得分:8)
比bareword(解释为文件句柄)或简单标量$var
更复杂的东西被解释为glob()
函数的参数。只有裸字和简单标量被视为文件句柄,由<...>
运算符进行迭代。
基本上规则是:
<bareword> ~~ readline bareword
<$scalar> ~~ readline $scalar
<$array[0]> ~~ glob "$array[0]"
<anything else> ~~ glob ...
答案 3 :(得分:6)
这是因为<$fh[0]>
被解析为glob($fh[0])
。
改为使用readline
:
my @res1 = readline($fh[0]);