11

代码

$ 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。这两种方法不一样吗?这里发生了什么?

4

4 回答 4

14

由于 <> 运算符的双重性质(即它是glob还是readline?),规则是作为 readline 的行为,你只能在括号内有一个裸词或一个简单的标量。因此,您必须将数组元素分配给一个简单的标量(如您的示例中所示),或者直接使用 readline 函数。

于 2010-11-29T15:39:17.320 回答
14

因为来自perlop

如果尖括号中的内容既不是文件句柄,也不是包含文件句柄名称、typeglob 或 typeglob 引用的简单标量变量,则将其解释为要通配的文件名模式,以及文件名列表或列表中的下一个文件名根据上下文返回。这种区别仅由句法基础决定。这意味着<$x>始终是间接句柄的 readline(),但<$hash{key}>始终是 glob()。

您可以将<>运算符拼写为readline以避免这种魔法出现问题。

于 2010-11-29T15:44:07.430 回答
8

任何比裸字(解释为文件句柄)或简单标量更复杂的东西$var都被解释为glob()函数的参数。只有裸字和简单的标量被视为文件句柄以供<...>操作员迭代。

基本上规则是:

<bareword> ~~  readline bareword
<$scalar>  ~~  readline $scalar
<$array[0]> ~~ glob "$array[0]"
<anything else> ~~ glob ...
于 2010-11-29T15:40:35.073 回答
6

这是因为<$fh[0]>被解析为glob($fh[0]).

改用readline

my @res1 = readline($fh[0]);
于 2010-11-29T15:39:48.130 回答