我以为我理解地图然而以下结果我不明白.我知道为什么会这样,我只是不知道它是怎么回事.
问题是@array的内容正在改变,因为$_在_do_stuff_to_file调用期间正在重置.所以印刷的是here: \nhere:\n我期待它的时候here: donkie\nhere: kong\n.
注意:这不是经过测试的代码.这就是我记得从实验室看到的东西.为什么内容会@array改变?
如果我在返回1之前设置$_为.然后阵列仍然完好无损.$f_some_func
这是一个示例程序来说明我所看到的:
my @array = ("donkie", "kong");
map { push @junk, _some_func('blah', $_); } @array;
if (join ('', @junk) !~ /0/)
{ # for example sake this is always true since return 1 from _some_func.
print map { "here: $_\n"; } @array;
}
sub _some_func
{ # for example sake, lets say $f always exists as a file.
my $j = shift;
my $f = shift;
return 0 if !open(FILE, "< $f");
close FILE;
_do_stuff_to_file($f);
return 1;
}
sub _do_stuff_to_file
{
my $f = shift;
open(IN, "< $f");
open(OUT, "> $f.new");
while (<IN>)
{
print OUT;
}
close IN;
close OUT;
}
Run Code Online (Sandbox Code Playgroud)
Perl中的许多函数都使用默认变量$_.其中有map和readline运算符<>.就像foreach,map使循环变量成为它处理的列表的每个元素的别名.发生的事情就是这条线:
while (<IN>)
Run Code Online (Sandbox Code Playgroud)
正在分配,$_而别名的map有效.这是使用$_(或任何其他全局变量)的问题之一 - 远处的奇怪动作.如果您要使用$_,请先将其本地化:
local $_;
while (<IN>)
...
Run Code Online (Sandbox Code Playgroud)
或者,使用词法变量:
while (my $line = <IN>)
Run Code Online (Sandbox Code Playgroud)