Perl 高階関数:File::Find
Perl のFile::Find 標準モジュールは高階関数の良い例だが、高階関数について知らない人には分かりにくいらしい。
まず、関数のリファレンスについて。Perl で関数をデータとして扱いたいとき、?& 関数名とすれば良い。逆に&関数名とすれば、元の関数に戻る。
sub fn { ... my $arg = shift; ... } my $function_data = ?&fn; &{$function_data}("var");
関数とデータの区別の無い Scheme などの言語と比べるとちょっと繁雑だが、十分合理的で簡単な仕組みだ。見た目は変数の後に関数への引数が来るので慣れないと変に感じるかもしれない。中括弧は付けた方が分かりやすい。
ここでつかえてしまう人は、配列のリファレンス渡しをちゃんと理解していないか、使っていない可能性が高い
(それはもちろん Perl が全然使えていない、と同意である)。
ここまでで、もう関数をデータとして扱えるようになったので、配列に格納したりハッシュに格納したり自由だ。
デザインパターンで言うところのテンプレートメソッドなどは簡単に実現できる。もちろんFile::Find モジュールは自由に使えるはずだ。
use File::Find; sub wanted { print $_ ."?n" if /?.lisp$/; } find (?&wanted, ".");
ついでに、どうせデータとしてしか使わない関数に名前を考えるのはめんどくさい、と考えたら、そのまま名前を省いた sub ブロック(無名関数)を使える。ときどき名前の無い関数に罪悪感?を感じる人がいるが、それは単に慣れていないだけで、気にしなくて良い。名前が説明のために必要なほど難しい処理をしてるなら付けても良いが、たぶんそんなことは無い。