2.10.4. リファレンス型変数#

Perl にはリファレンス型の変数が用意されています。一般的な変数は値そのものを保存しますが、リファレンス型の変数は値が格納されているメモリアドレスを保存します。これを利用することで、二次元配列、二次元ハッシュ、配列のハッシュなど、複雑なデータ構造を扱うことができます。

2.10.4.1. 宣言#

リファレンス型の変数も、変数名の前に $ を付けて宣言します。そのため、見た目は通常のスカラー変数と区別しにくくなっています。リファレンス変数にはアドレスが保存されるため、利用する際には、代入対象となる変数のアドレスを取得する必要があります。アドレスを取得するには \ 演算子を使用します。

リファレンス変数に配列を代入する方法は 2 通りあります。1 つ目は、配列 @arr を先に作成し、そのアドレスを $ref_arr に代入する方法です。2 つ目は、配列を明示的に作成せず、最初からリファレンス変数に直接配列を代入する方法です。

my @arr = ('A', 'C', 'G', 'T');
my $ref_arr = [];
$ref_arr = \@arr;

my $ref_arr = ['A', 'C', 'G', 'T'];

ハッシュをリファレンス変数に代入する場合も、配列と同様に 2 通りの方法があります。

my %hash = ('AUG' => 'M', 'GUA' => 'V');
my $ref_hash = {};
$ref_hash = \%hash;

my $ref_hash = {'AUG' => 'M', 'GUA' => 'V'};

2.10.4.2. リファレンス変数から値を取得#

リファレンス変数にはアドレスが保存されています。変数名の前に $ を付けることで、そのアドレスを参照します。

例えば、通常のスカラー変数のリファレンスを用いると、以下のように $$ によって元の値を取得できます。

my $pi = 3.14;
my $ref = \$pi;

print $ref;
## SCALAR(0x1148d88)

print ${$ref};
## 3.14

$$ の意味は次のように考えると理解しやすくなります。まず $pi = 3.14 が定義されています。次に $ref = \$pi が定義されています。このとき $\ は関数とその逆関数のように考えることができ、$$ref = $($ref) = $(\$pi) = $pi = 3.14 となります。

配列の場合は、アロー演算子 -> を用いて各要素を取得します。

my @arr = (1, 1, 2, 3, 5, 8, 13);
my $ref = \@arr;

print $ref->[0]; 

print $ref->[3];

配列のすべての要素を取得する場合は、以下のように for 文を用います。

my $ref = [1, 1, 2, 3, 5, 8, 13];

for (my $i = 0; $i < @{$ref}; $i++) {
    print $ref->[$i];
}

ここで $ref には配列のアドレスが保存されています。@{$ref} と記述することで、$ref が指すアドレスをたどって配列を取得し、通常の配列として扱うことができます。

ハッシュの場合も、アロー演算子 -> を用いて各要素を取得します。

my %hash = ('AUG' => 'M', 'GUA' => 'V');
my $ref = \%hash;

print $ref->{'AUG'};

print $ref->{'GUA'};

すべてのキーと値を取り出す場合は、配列と同様に %{$ref} を用いてリファレンスをハッシュに復元してから、for 文や while 文を利用します。

my $ref = {'AUG' => 'M', 'GUA' => 'V'};

for my $key (keys %{$ref}) {
    print $ref->{$key};
}

while (my ($key, $val) = each %{$ref}) {
    print "$key   ===>   $val";
}