为什么在Perl中无法使用钻石操作符来处理数组?

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个回答

14

由于 <> 操作符的双重性质(即它是 glob 还是 readline?),因此规则是为了像 readline 一样运行,你只能在括号内放置一个裸字或一个简单标量。所以你要么将数组元素分配给一个简单标量(就像你的例子中一样),要么直接使用 readline 函数。


perl -le 'print for < < <=> > >' - tchrist
@tchrist:除了作为glob的有趣示例之外,还有什么意义吗? - runrig

14

因为从perlop得知:

如果尖括号内的内容既不是文件句柄也不是包含文件句柄名称、类型字节或类型字节引用的简单标量变量,则被解释为要进行glob操作的文件名模式,并返回文件名列表或列表中的下一个文件名,具体取决于上下文。这种区别仅根据语法确定。这意味着<$x>始终是从间接句柄读取(readline() ),但<$hash{key}>始终是从glob()读取。

您可以将<>运算符称为readline,以避免在使用此功能时出现问题。


8

除了裸字(解释为文件句柄)或简单的标量$var之外,任何更复杂的内容都会被解释为glob()函数的参数。只有裸字和简单标量才被视为文件句柄,可以由<...>操作符迭代。

基本规则如下:

<bareword> ~~  readline bareword
<$scalar>  ~~  readline $scalar
<$array[0]> ~~ glob "$array[0]"
<anything else> ~~ glob ...

6

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

可以改用readline替代:

my @res1 = readline($fh[0]);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接