無名サブルーチンとクロージャ
昨日言っていた『インナーサブルーチンを使って親のレキシカル変数をリターン値にすると、初回の値を保持するようなのです』の性質を利用するとstatic変数だけでなく、クロージャも出来ますね!
◆サンプル(closure.pl)
use strict; use warnings; sub closure { my $value = shift; sub { $value++ }; } my $c = closure(100); print $c->(), "\n"; print $c->(), "\n"; print $c->(), "\n"; print $c->(), "\n";
◆実行結果
C:\samp_pl>closure.pl 100 101 102 103
closureサブルーチンを初回コールすることにより、$valueに初期値をセットし、$valueをカウントする無名サブルーチンリファレンスを返します。この時点で$valueはstatic変数になっていますね。
そのリファレンスをスカラー変数($c)へ代入し、無名サブルーチンを実行するとstatic変数$valueがカウントされ100〜103のように出力されるわけです。
と、大まかに説明しましたが、無名サブルーチン『sub { $value++ };』のところをもうちょっと詳しく説明します。
名前の無いサブルーチンを無名サブルーチンといいます(まんま)。
無名サブルーチンは、名前が無いのでスカラー変数に代入したり、return値に指定したりします。
今回はreturn値に指定しています。ただし、returnキーワードは省略されています。
その指定された値は、サブルーチンのリファレンスになっています。
無名サブルーチンを実行するには、代入したスカラー変数からデリファレンスの『->』とサブルーチンの『()』を繋げて『$c->()』という感じで実行します。
また、Perlのサブルーチンでは最後に評価された式がreturn値になりますので、上記のclosureは以下と等価なのです。
sub closure { my $value = shift; return sub { return $value++; }; }
初心者の内は、この辺でつまずくんだよなぁ・・・。
それから、クロージャそのものについては、私も詳しくないのでネットで検索してください。