マイブーム?

 最近のマイブーム(その表現自体もう古いかな)は map。map と言っても地図の事じゃなくて perl で言うところの関数 map だ。

 あ、perl 熟練者には物足りないかと。

 この関数が存在するのは以前から知っていたしけっこう見かけていたものの、イマイチその動作がよく分からなかったというかどういう機能を持っているのかが分からなかった。perl のソースってパズルみたいだし…。それがいつオールクリアというか霧が晴れたというか何をするのかが分かったのはいつだったか定かではないけど、けっこう最近の事だと思う。それで嬉しくなって本当に必要なのかどうかもよく考えずに map 関数を使いまくっている。いいのかそんなんで。

 さて、map 関数というのは

map 式/ブロック 配列

 という書式を取る。渡された「配列」を順番に $_ に入れてそれぞれ「式/ブロック」の処理を行い、その結果を配列として返す関数だ。

 たとえばこんな感じ。配列の数値を10倍にするもの。

@a = (1..10);
@b = map {$_ * 10} @a;

 これで @b の内容は (10,20,...,100) となる。ちなみにブロックの中の $_ は配列の内容を参照しているため、$_ を書き換えると配列の中身が変わってしまう。つまり {$_ = $_ * 10} とすると @a 自体が (10,20,...,100) となってしまうので注意が必要だ。

 これだけではあまりにも簡単すぎるためもうちょっと複雑な例を。

my %formdata = ();
map { $formdata{$_} = ${$_} if defined ${$_}; } qw{url title excerpt blog_name charset};

 これはある関数の一部。後ろの方に並んでる名前から何をする物かピンと来る人もいるかもしれない。

 分からない人も居るかも知れないから一応解説を。

 後ろの qw{url...charset} と言う部分。これは後ろに並んでいる物をスペースを区切りとして分解して配列にして返すと言う物だ。ちなみに qw/.../ としても同じなんだけど括弧にすると括弧の対応を perl が見てくれるから、qw{a {b} c} と書いてもエラーにはならない。まあ今回の例では括弧にする必要は全く無いんだけど。

 そしてもう一つ。${$_} の部分。たとえば $_ が url ならば $url の内容、と言うことになる。これはあることを調べているときに見つけたPerlメモと言うサイトに書いてあった。「その場でスカラー変数を作る」という項目の部分だ。

 これをわかりやすく書くと次のようになる。

$formdata{url} = $url if defined $url;
$formdata{title} = $title if defined $title;

 以降同じ物が続くため省略したが、こうやって羅列するより遙かにマシだろう。foreach でも代用できるだろうけど、map は速いって聞いた。いや読んだ…かも。ちょっと覚えていない。というかこの程度では速度差は出なさそうだけど。

 もう一つ。

my $query = 'mode=list&part=all';
my($a,$b);
undef %param;
map {($a,$b) = split /=/; $param{$a} = $b;} split /&/,$query;
  (何らかの処理)
$query = join '&',map { "$_=".${URLe($param{$_})} } keys %param;

 $query は、cgi に GET するときのパラメータ部分。実際のプログラムではこんな宣言はしてないけど例として。

 処理の内容としては $query を分解し、%param という連想配列に格納、必要な処理を施して元の形に戻す。その際 urlencode も同時に行う。

 URLe と言うのが urlencode を行う関数だけどこれは組み込み関数ではない。さっきと同じPerlメモに載っている関数。${URLe($param{$_})} と言う風に ${ } で囲んでいるのは、URLe の返値が参照型だからこうしないと実際の内容が取得できない。同サイトによると、この返し方にすると変数のコピーが起こらないためにメモリの節約、速度的に有利、と言う利点があるらしい。巨大な配列でしかあまり恩恵は受けられないだろうけど。

 こういう例を見ると、冒頭でも書いたけどやっぱ perl ってパズルみたいだなあと思ってしまう。というかそれを逆に楽しんでいるような気さえする。落ち着いて順番に分解していけば処理内容は分かるんだけど、ややこしいから途中で飽きてしまう。そんなことが何度あったことか。

 しかしこんなややこしい文をよくもまあ正確に perlインタプリタは理解できるもんだ。まあきちんとした書式があるわけで、こういう物の解析は機械の得意とする分野かもしれないけど。