無名関数(クロージャ)

無名配列や無名ハッシュと同じように、無名の関数(サブルーチン)へのリファレンスも簡単に作成する事ができます。
無名で関数が作れると何が便利なんでしょうか。
例えば、微分のように返り値として関数を生成して返す関数(高階関数)を作りたい場合、関数を「値」として受け渡ししなければなりません。こういった場合、通常の名前付き関数宣言では実現できません。
無名の関数は「匿名関数」「クロージャ」「ラムダ式(これはちょっと違いますが)」などとも呼ばれ、SchemeHaskell などの関数型プログラミング言語ではよく登場します。抽象化にとても便利な機能です。
無名関数へのリファレンスは sub を名前なしで使えば作る事ができます。関数定義を勉強した時に出てきましたね。
デリファレンスはもちろん頭に「&」をつけるだけです。または、矢印演算子「->」を使う事もできます。
コードを書いてみます。

# ref5.pl
 
my $funcref = sub { print "@_\n"; };  # 文末の「;」に注意
 
&$funcref("apple", "banana", "orange");
$funcref->("apple", "banana", "orange");

引数を print する無名関数のリファレンスを $funcref に代入しています。文ですので、文末のセミコロン(;)は必要です。注意してください。
後の2文は同じ意味ですね。矢印演算子を使ったほうが読みやすいでしょうか。
実行結果です。

apple banana orange
apple banana orange

ではでは、次に応用として「関数を受け取って実行する関数」を考えてみます。

# ref6.pl
 
sub hellofunc {
	my $func = shift;
	return $func->("Hello!");
}
 
hellofunc( sub { print "@_\n"; } );         # (1)
hellofunc( sub { print "@_ World!\n"; } );  # (2)
 
my $decorator = sub {
	return "***" . shift() . "***";
};
print hellofunc($decorator), "\n";          # (3) 

関数 hellofunc は、引数として関数へのリファレンスを受け取り、受け取った関数に "Hello!" という文字列を渡してコールしています。そしてその返り値をそのまま返します。
(1)と(2)では無名関数のリファレンスを直接渡しています。(1)は引数をそのままprintする関数、(2)は引数の後ろに World! とつけてprintする関数を渡しています。
(3)では引数の前後に***を付けた文字列を返す関数を渡しています。この場合、一旦変数に入れているので、名前が付いた関数を使ってるのと、あまり変わりませんね。
以下が実行結果です。

 Hello!
 Hello! World!
 ***Hello!***