燈明ブログ

現状は小池啓仁の応援ブログ

配列のインデックスでなく、インデックスの配列?

以下は、弾さんのブログで、たまたま見つけました。
なんか、配列をインデックスに使用していますね。
普通は、配列に対してインデックスがあるのに、以下は配列がインデックスになっています。
つまり、配列のインデックスでなく、インデックスの配列?

◆ 引用(サンプル)

sub make_akhash {
    return sub : lvalue {
        $val{join($;,@_)}
    }
}

my @array  = qw/1 2 3/;
my @array2 = qw/1 2 3/;

my $h = make_akhash();
$h->(@array) = 'foo';
print $h->(@array2);
http://blog.livedoor.jp/dankogai/archives/50936712.html

たったこれだけのロジックだけど、理解するのに3つのハードルがありますね。

  • クロージャ
  • 『$;』多次元配列のエミュレートのための添え字
  • 『: lvalue』左辺値サブルーチン

クロージャ

関数のリターン値に関数リファレンスを指定して、関数リファレンスが関数の内部変数を使用すると、その変数はスコープを抜けても生きつづけ、カウントアップ等が可能になることかな・・・。

あと、引用のソースには、%valの宣言がありませんね、実際は、以下の感じですかね。

sub make_akhash {
    my %val;
    return sub : lvalue {
        $val{join($;,@_)}
    }
}

◆『$;』多次元配列のエミュレートのための添え字

『$;』はセミーセミコロンといわれ?、ハッシュキーでの見た目はセミコロンだけど、実際のデフォルト値は『\034』とのことです。
つまり、ハッシュのキーにバイナリ値を使う場合は、エミュレートできないということです。
なぜなら、バイナリ値はすべてのコードが対象で、当然『\034』が含まれるからです。

◆『: lvalue』左辺値サブルーチン

普通は変数へ代入しますが、これ、サブルーチンへ代入ができるのです。
それには、sub文のサブルーチン名の後ろに「: lvalue」を追加します。(引用サンプルでは無名サブルーチンなのでsub文の後ろに追加)
そして、代入値は、サブルーチンで一番最後に評価する変数に代入されるみたいです。
詳しくは以下を参照してください。