[Perl]猿でもわかるクロージャ超入門

[JavaScript] 猿でもわかるクロージャ超入門という記事が好評だったので、今回はPerl編です。
上記のJavaScript版の記事を読んだという前提で解説させていただきます。

問題

呼び出すたびに、1,2,3,...を返すような関数f( )を定義せよ。
f();  //  1 
f();  //  2
f();  //  3

クロージャ その1

JS版のクロージャに似せて書くとこうなります。
#!/usr/bin/perl

use strict;
use warnings;

sub outer {
    my $i = 1;

    return  sub {
        print "$i\n";
        $i++;
    };

}

my $f = outer();

$f->(); # 1
$f->(); # 2
$f->(); # 3

JS版とそっくりですね~。

関数のリファレンスを使っているので、呼び出し方法が$f->()のような形になっちゃいますが、そこはご愛嬌ということで。

クロージャ その2

JSと違ってPerlでは中カッコ{}でスコープを作ることができるので、より簡潔に書けます。

#!/usr/bin/perl

use strict;
use warnings;

my $f;
{
    my $i = 1;

    $f = sub {
        print "$i\n";
        $i++;
    };

}

$f->(); # 1
$f->(); # 2
$f->(); # 3

クロージャ その3

Perlではローカルスコープ内で宣言した関数を、スコープ外から参照することができます。
これを利用すると、さらに短く書けます。

#!/usr/bin/perl
use strict;
use warnings;

{
    my $i = 1;

    sub f {
        print "$i\n";
        $i++;
    }

}

f();
f();
f();

以上、Perlでのクロージャの作り方でした。
他にもいろいろ書き方があると思います。

Perlってサイコー!!

クロージャの使われどころ

PerlにはClass::AccessorやClass::Data::Inheritablenaといった、オブジェクト指向をより便利にするための定番モジュールがあります。
これらのモジュールでは、クロージャを使うことによってアクセサを実現しています。

参考
カテゴリ: