お知らせ

現在サイトのリニューアル作業中のため、全体的にページの表示が乱れています。

Perlでの配列の扱い方を観察してみる

投稿日:
言語::Perl

Perlで配列を初期化するときにいろいろ試したので、そのログ

確認環境

Env Ver
Perl 5.34.0

初期化方法

配列変数を配列で初期化

@始まりの変数に()で配列リストを作成して初期化する。

my @hoge = (1, 2, 3);
# 3<>1 2 3
print @hoge."<>@hoge\n";

配列変数をそのまま呼び出した場合は配列の長さが、文字列にするとスペース区切りになったものが出てくる。

配列変数を配列以外で初期化

@始まりの変数に配列以外を入れて初期化する。

my @hoge = 3;
# 1<>3<>3
print @hoge."<>@hoge<>$hoge[0]\n";

この場合は暗黙的に配列が作成され、ゼロ番目の要素にその値が入る。

配列変数を無名配列で初期化

前項の応用。参考までに無名配列で初期化した場合、[0]に無名配列が入り、二重配列になる。

my @hoge = [1, 2, 3];
# 1<>ARRAY(0x55e45749d860)<>ARRAY(0x55e45749d860)<>1<>2<>3
print @hoge."<>@hoge<>$hoge[0]<>$hoge[0][0]<>$hoge[0][1]<>$hoge[0][2]\n";

スカラ変数を配列で初期化

スカラ値にキャストされ、配列長が入る。これは配列変数をそのまま使った場合同様の振る舞い。

my $hoge = (1, 2, 3);
# 3
print $hoge."\n";

スカラ変数を無名配列で初期化

そのままでは配列として扱うことができず、配列として扱うためには@{ $var }形式にする必要がある。

my $hoge = [1, 2, 3];
# ARRAY(0x5596ea845de0)<>ARRAY(0x5596ea845de0)<>3<>1 2 3
print $hoge."<>$hoge<>".@{ $hoge }."<>@{ $hoge }\n";

またハッシュを配列として扱う場合は、この形式になり@{ $hash->{hoge} }のようにして扱う。

ハッシュ初期化時にキーを配列で初期化

配列が分解されてハッシュになるため、意図した値が入らない

my $hash = { hoge => (1, 2, 3) };
# 1<>1
print $hash->{hoge}."<>$hash->{hoge}\n";

実際にできる構造

$VAR1 = {
  'hoge' => 1,
  '2' => 3
}

ハッシュ初期化時にキーを無名配列で初期化

基本的にはこれで初期化するといい。使い方は「スカラ変数を無名配列で初期化」と同様

my $hash = { hoge => [1, 2, 3] };
# ARRAY(0x55599ba8dd08)<>3<>1 2 3
print $hash->{hoge}."<>".@{ $hash->{hoge} }."<>@{ $hash->{hoge} }\n";

ハッシュのキーに配列を代入

@{ $var }構文でやると上手く入る。普通に代入するとスカラ値になるので配列長が入る

my $hash = { hoge => undef };
@{ $hash->{hoge} } = (1, 2, 3);
# ARRAY(0x564efec0e4e8)<>3<>1 2 3
print $hash->{hoge}."<>".@{ $hash->{hoge} }."<>@{ $hash->{hoge} }\n";

ハッシュのキーに無名配列を代入

my $hash = { hoge => undef };
$hash->{hoge} = [1, 2, 3];
# ARRAY(0x55844312a4e8)<>3<>1 2 3
print $hash->{hoge}."<>".@{ $hash->{hoge} }."<>@{ $hash->{hoge} }\n";

備考

配列と無名配列の違いについて

配列は配列の実体そのもので、無名配列は参照らしい。

恐らくスカラ変数に無名配列を入れた場合、変数そのものには配列への参照が入るので、ARRAY(0x5596ea845de0)的な値が出てくるが、@{ $var }とすると参照先の実体が見れるので、配列として扱うことができるようになるのだと思う。

反対に配列変数の場合は、基本的に配列の実体を見るようになっていて、文字列化するときのみ参照が取れるようになっているように見える。

詳しくは以下の資料を参照するとわかる気がするので、また暇なときにでも見てみようと思う。

最近は値と参照の境界が分かりづらくなっている気もするので、Perlのこう言った書き口は少し面白いなと思った。要するにポインタを明示的に扱える訳だ。