map, grepのブロックの中でreturnするとそのブロックではなくその外側のブロック(サブルーチンなど)からreturnする。
perl v5.14.2で確認。
return.pl
use strict;
use warnings;
use feature qw(say);
use List::Util qw(first reduce);
sub custom1(&) {
shift->();
}
sub custom2(&@) {
shift->();
}
sub test_grep {
my @a = (1);
@a = grep { return 'from inside grep' } @a;
return 'from outside grep';
}
sub test_map {
my @a = (1);
@a = map { return 'from inside map' } @a;
return 'from outside map';
}
sub test_eval {
eval { return 'from inside eval' };
return 'from outside eval';
}
sub test_first {
my @a = (1);
@a = first { return 'from inside first' } @a;
return 'from outside first';
}
sub test_reduce {
my @a = (1);
@a = reduce { return 'from inside reduce' } @a;
return 'from outside reduce';
}
sub test_custom1 {
custom1 { return 'from inside custom1' };
return 'from outside custom1';
}
sub test_custom2 {
my @a = (1);
@a = custom2 { return 'from inside custom2' } @a;
return 'from outside custom2'
}
say test_grep;
say test_map;
say test_eval;
say test_first;
say test_reduce;
say test_custom1;
say test_custom2;
上のコードを実行すると、結果は
from inside grep
from inside map
from outside eval
from outside first
from outside reduce
from outside custom1
from outside custom2
evalやコードブロックを取るユーザ関数はreturnでブロックを抜けるが、grep,mapは違う。見た目はほとんど変わらないのに。まあ、そういうものだと思うしかないか。