Perl6 の参照の話

というわけで、アドベントカレンダーを登録してないけどそんな気持ちでクソエントリを書いていこうと思う。

前もやったかもしれないけど、Perl6 の参照の話をしよう。

my @puyo = (1, 2, 3);

簡単な配列を入れた @puyo を宣言する。
そして、それを $myon に入れる。

my $myon = @puyo;

ここで、$myon は何を持っているだろう?それは、@puyo が持っている配列の参照だ。
えーと、配列の参照って?

╰( ´◔ ω ◔ `)╯ わからん

じゃあ、$myon をまた別の配列変数に入れてみよう:

my @hunyo = $myon;

ここで @hunyo@puyo は等価だろうか?
say で中身を表示してみよう:

[[1 2 3]]

違う。
@hunyo の中身は [[1, 2, 3]] となぜかネストした配列になっている。
これは、$myon には配列そのものではなく、配列のリファレンスが入っていることが原因だ((おそらくそうなんだろうなと言う意味))。

別の表現をすると、配列型の変数には配列しか設定できないため、スカラー変数の値を配列変数に設定した場合、暗黙のキャストが起こり、配列は配列の配列へと変容してしまう。
これを防ぐには、変数の前に | (パイプ)を付ける:

my @hunyo = |$myon;

このような現象は以下のように Map の値が配列であるというような場合に起こりやすい:

my  %already  = (
    authors => ['John Due']
);

{
    my @authors = do if %already<authors>:exists {
        %already<authors>                             # %already<authors> はスカラーを返す! パイプを使え!
    } else {
        []
    };

    say @authors;                                     # ウボァーーーーー!!!! @authors は [['John Due']] だ!!!!
}

私はJSON を扱う際にこの現象にぶち当たり、うぎゃーーーーーとなった。
みなさんも Perl6 を書く時には注意して欲しい。