而在 foreach 内部会杀死原始数组

while inside foreach kills original array

出于某种原因,我的原始数组被这段代码清除了。我不明白为什么? @my_array 在 运行 之后为空,我取出了 while 循环中的所有工作以查看是否是原因,但不是。

foreach (@my_array)
{
    open MY_FH, "<", $_;
    while (<MY_FH>)
        {
        }
    close MY_FH;
}

它不是空的,它只是充满了undef

while (<MY_FH>)while (defined($_ = <MY_FH>)) 的语法糖。由于 foreach 循环中的变量是原始值的别名,因此 $_ 中的文件名会被文件的每一行覆盖。 while 循环一直持续到 <MY_FH> returns undef 指示 EOF。 undef 是存储在 $_ 中的最后一个值。

解决方案是在至少一个循环中使用不同的变量。更改 foreach 循环可能会减少工作量:

foreach my $fn (@my_array)
{
    open MY_FH, "<", $fn;
    while (<MY_FH>)
        {
        }
    close MY_FH;
}

如果在 scalar @my_array 循环后检查 @my_array 的大小,您会发现它没有改变。但是当您访问单个元素时,undef 的数组看起来就像一个空数组,这可能就是您认为它为空的原因。

正如 cjm 所解释的,数组的元素被 while 循环覆盖,因为它从文件读取到 $_foreach 为每个数组元素起别名反过来

最简单的解决方案是在 while 循环期间 localise $_。这会创建 $_ 的临时副本,可以在不影响 @my_array 的情况下使用。像这样

for ( @my_array ) {

    open my $fh, '<', $_;

    local $_;    # To protect @my_array

    while ( <$fh> ) {
        ...
    }
    close $fh;
}