以下代码将包含@populations中的内容
@populations=("EUR","AFR","ASN","AMR");
print @populations,"\n"; #will show EURAFRASNAMR
foreach (@populations)
{
$filepath="tmp.txt"; #whatever text file you like
open(FILE,"<$filepath");
while(<FILE>)
{
}
}
print @populations,"\n"; #will print nothing
如果改为
foreach $i (@populations)
那么阵列就不会被吃掉。
或者如果标记while循环,则不会吃掉数组。
我不是一个perl guru,但有几年的经验。
谁能告诉我为什么?它是perl的一个bug吗?
答案 0 :(得分:6)
不是一个错误的错误,但它是一个疏忽的陷阱。您隐式将@populations
的元素分配给$_
变量,然后您正在将FILE
文件句柄中的数据读入$_
,覆盖@populations
的内容}。
更明确地说,您的代码相当于:
@populations=("EUR","AFR","ASN","AMR");
print @populations,"\n"; #will show EURAFRASNAMR
foreach $_ (@populations) # $_ becomes "aliased" to the element in @populations
{
$filepath="tmp.txt"; #whatever text file you like
open(FILE,"<$filepath");
while(defined($_ = <FILE>)) # overwrites $_, and erases element in @populations
{
}
}
print @populations,"\n"; #will print nothing
您找到了一个很好的解决方法,即避免在$_
循环中隐式使用for
。
答案 1 :(得分:5)
while (<$fh>) { ... }
替换为
while (defined($_ = <$fh>)) { ... }
这就是$_
中可读取的值的原因。问题在于,$_
当前是@populations
元素的别名。
正如您所说,您可以使用
来避免这个问题for my $population (@populations) {
...
while (<FILE>) { ... $_ ... }
...
}
但是仍然可以从调用子中删除$_
。以下是两个更强大的修复程序:
for (@populations) { # Or: for my $population (@populations) {
...
while (my $line = <FILE>) { ... $line ... }
...
}
或
for (@populations) { # Or: for my $population (@populations) {
...
while (local $_ = <FILE>) { ... $_ ... }
...
}
出于完全相同的原因,您不应将全局变量用于文件句柄。
$filepath="tmp.txt"; #whatever text file you like
open(FILE,"<$filepath");
<FILE>
应该是
my $filepath="tmp.txt";
open(my $FILE, "<", $filepath) or die $!;
<$fh>
顺便说一句,请始终使用use strict; use warnings;
。