mapした結果がundefのものを除いた配列を得る

知らなかった。。

my @arr = (
    { key => 1 },
    { key => 2 },
    { key => undef },
    { key => 3 }
);

のようなデータに対し、全要素の"key"に対応する値を取り出したmapを得ると

print "$_\n" for map { $_->{key} } @arr;
1
2
Use of uninitialized value $_ in concatenation (.) or string ...

3

となる。mapの結果はundefも含む4要素の配列ということになる。
ここからundefのやつを除きたい、というとき、今までずっと

print "$_\n" for (grep { defined } map { $_->{key} } @arr);

ってやってmap後のものをdefinedで篩にかけてた。けど

print "$_\n" for (map { defined($_->{key}) ? $_->{key} : () } @arr);

のようにundefのときに空の配列を返すようにするとそのぶんが除かれた配列が最終的に得られるようになるんですね。