Perl5 リファレンス



grep

【文法】

grep BLOCK LIST
grep EXPR,LIST


【説明】

これは、同じではありませんが、気持ち grep(1) に似ています。特に、それは、正規表
現を使うことに限定していません。

(局所的に $_ を各要素にセットされた)LIST の各要素に対して、LISTBLOCK や EXPR 
を評価します。そして、真と評価された要素からなるリストを返します。スカラーコンテ
キストでは、真と評価された回数が返されます。

    @foo = grep(!/^#/, @bar);    # weed out comments
    @foo = grep {!/^#/} @bar;    # weed out comments
    以上 2 つは、同等です。

$_ はリストの値へのリファレンスですから、grep 関数で配列の要素を変更することがで
きます。これは便利でサポートされている一方、LIST が名無し配列の場合には、怪奇な
結果を引き起こす可能性があります。for ループの index 変数がリスト要素に別名をつ
けるのと同様に、grep 関数はオリジナルのリストの中へのエイリアスを返します。つま
り、(例えば、foreach, map や他の grep内の)grep 関数から返されたリストの要素を
修正することは、正確にはオリジナルのリスト内の要素を修正しているということになり
ます。これは、通常、クリアコードを書く時に避けられるべきことです。


【使用例】

my @LIST = ('TANAKA', 'SATO', 'SUZUKI', 'SAITO');
my @array = grep(/TO/, @LIST);

この場合、配列 @LIST 内の要素の中で、'TO' という文字列が含まれる要素を取り出し、
配列 @array に格納します。@array には、'SATO', 'SAITO' の 2 つの要素が格納されま
す。

my $num = grep(/TO/, @LIST);

この場合には、左辺がスカラー変数ですから、@LIST 内の要素で 'TO' がマッチした要素
数を返すことになります。$num には、2 が格納されます。

さて、上記説明で、grep 関数から返されたリストを変更するとオリジナルのリストが変
更されてしまうという現象を検証してみましょう。

my @LIST = ('TANAKA', 'SATO', 'SUZUKI', 'SAITO');
my $key;
for $key (grep(/TO/, @LIST)) {
	$key = 'hogehoge';
}

上記例では、@LIST 内から 'TO' を含む要素に対して、for ループを組み、index 変数と
して $key を割り当てています。つまり、'TO' を含む要素が $key に格納され(正しく
は、$key に オリジナルの要素へのリファレンスが割り当てられ)、その $key を 
'hogehoge' という文字列に変更しています。
すると、オリジナルの @LIST の 'SATO' と 'SAITO' の 2 つの要素は、それぞれ 
'hogehoge' という文字列に置き換わってしまいます。
grep 関数を使う際には、このことを念頭において利用しましょう。



Perl5リファレンスに戻る