ハッシュのリファレンス
Perlにはハッシュのリファレンスというデータ構造が頻繁に登場します。このページでは、リファレンスの中からハッシュのリファレンスを詳しく取り上げます。
ハッシュのリファレンスとは
ハッシュのリファレンスとは、ハッシュに対するリファレンスのことです。リファレンスというのは、指すということを表します。ハッシュに対して、リファレンス生成子「\」を使用すると、ハッシュのリファレンスを作成することができます。
# ハッシュのリファレンスを作成 my %score = (math => 68, english => 90); my $score_ref = \%score;
ハッシュのリファレンスは、スカラ変数に代入されるとういうことに注意してください。
ハッシュのリファレンスのイメージを以下に書いてみます。
# イメージ %score $score_ref -------> (math => 68, english => 90)
ハッシュのリファレンスは、ハッシュそのものではなく「ハッシュを指し示すもの」を表現します。
ハッシュのリファレンスは代入で中身がコピーされない
ハッシュとハッシュのリファレンスの違いをここから見ていきましょう。
ハッシュは、代入によって、中身がすべてコピーされますが、ハッシュのリファレンスはコピーが行われません。
# ハッシュは値がコピーされる my %score1 = (math => 68, english => 90); my %score2 = %score1; # ハッシュのリファレンスは値はコピーされない my %score1 = (math => 68, english => 90); my $score_ref1 = \%score1; my $score_ref2 = $score_ref1;
以下はイメージです。ハッシュの場合は、中身すべてがコピーされるのに対して、ハッシュのリファレンスは、中身ではなく、リファレンスそのものがコピーされます。
# イメージ %score1 %score2 (math => 68, english => 90) (math => 68, english => 90) $score_ref1 ------------> $score_ref2 ------------> (math => 68, english => 90)
サブルーチンに渡す場合は、ハッシュのリファレンスを渡す方が、中身のコピーが行われないので、効率が良くなります。
# サブルーチンにハッシュのリファレンスを渡す my_func($score_ref1);
無名ハッシュ生成子
ハッシュのリファレンスは、リファレンス生成子「\」を使用すると作成できますが、少し手間がかかります。すぐにハッシュのリファレンスを作成するために、無名ハッシュ生成子と呼ばれる演算子が定義されています。
my $score_ref = {math => 68, english => 90};
通常のハッシュが「()」で作成されるのに対して、ハッシュのリファレンスは無名ハッシュ生成子「{}」を使って生成されているのに注意してください。
Perlのソースコードでは、この記法が頻繁に登場します。ハッシュなのか、ハッシュのリファレンスなのかをソースコードから読み取ることが大切です。
# ハッシュ my %score =(math => 68, english => 90); # ハッシュのリファレンス my $score = {math => 68, english => 90};
デリファレンス
ハッシュのリファレンスを生成するには、リファレンス生成子を使いました。今度は反対にハッシュのリファレンスから、ハッシュを取り出してみましょう。
そのためにはデリファレンスという操作を行います。
my $score_ref = {math => 68, english => 90}; # デリファレンス my %score = %{$score_ref};
デリファレンスは「%{ハッシュのリファレンス}」という記法を使って行うことができます。
ハッシュのリファレンスがスカラ変数の場合は「{}」を省略することもできます。
my %score = %$score_ref;
標準関数に引数として渡す
keys関数、values関数、each関数などのハッシュに関する関数は、引数にハッシュをとります。そのため、ハッシュのリファレンスを渡したい場合は、デリファレンスする必要があるので注意してください。
# デリファレンスして標準関数に渡す keys %$hash; values %$hash; each %$hash;
ハッシュのリファレンスからハッシュの値を取り出す
ハッシュのリファレンスからハッシュの値を取り出すにはアロー演算子「->」を使うことができます。
# ハッシュのリファレンスからハッシュの値の取得 my $score_math = $score_ref->{math}; # ハッシュのリファレンスからハッシュの値を設定 $score_ref->{math} = 67;
アロー演算子が使われている場合は、ハッシュのリファレンスです。そうでない場合は、ハッシュです。これもソースコードの中で、しっかり読み取れるようになってください。
# ハッシュの値の取得 my $score_math = $score{math}; # ハッシュの値を設定 $score{math} = 67;
アロー演算子のあるなしだけで、ハッシュなのかハッシュのリファレンスなのかが異なるので、しっかり見ることが大切です。
配列のリファレンス
ハッシュのリファレンスと同じくらい頻繁に利用されるものとして配列のリファレンスがあります。
my $nums_ref = [1, 3, 5];
配列のリファレンスについては以下で詳しく解説しています。