查看perl文档,发现其中有一个被忽略的细节。对于$_,不能轻易修改它的值。
grep BLOCK LIST
Note that $_ is an alias to the list value, so it can be used
to modify the elements of the LIST. While this is useful and
supported, it can cause bizarre results if the elements of LIST
are not variables.
$_是原列表中元素的别名,修改$_,其实是修改原列表中的元素。
Similarly, grep returns aliases into the
original list, much as a for loop's index variable aliases the
list elements. That is, modifying an element of a list
returned by grep (for example, in a "foreach", "map" or another
"grep") actually modifies the element in the original list.
This is usually something to be avoided when writing clear
code.
如果在foreach、map、grep中嵌套使用grep,那么grep返回的是一个由别名组成的列表。其中每一个元素都指向原列表中的元素。如果在foreach、map或者外层grep中修改$_,则原列表的元素会被修改。
Example 1
my @origArray = ('Jan', 'Feb', 'Mar', 'Apr');
print "@origArray\n";
#Output
#Jan Feb Mar Apr
grep {/.*a.*/; $_ .= 'grep'} @origArray;
print "@origArray\n";
#Output
#Jangrep Febgrep Margrep Aprgrep
在grep的BLOCK中,修改了$_的值,导致原列表中的值被修改。
Example 2
my @origArray = ('Jan', 'Feb', 'Mar', 'Apr');
print "origArray : @origArray\n";
#Output
#origArray : Jan Feb Mar Apr
print "foreach : ";
foreach my $element (grep {/.*a.*/} @origArray) {
$element .= 'foreach';
print "$element ";
}
print "\n";
#Output
#foreach : Janforeach Marforeach
print "origArray : @origArray\n";
#Output
#origArray : Janforeach Feb Marforeach Apr
在foreach中,修改了Jan和Mar的值,导致origArray中对应的元素也被修改了。