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 を書く時には注意して欲しい。