Perl/リファレンス

出典: フリー教科書『ウィキブックス(Wikibooks)』

プログラミング > Perl > リファレンス

目次

[編集] 多次元配列

配列の中に配列が入っているものを多次元配列といいます。Perlで多次元配列を生成するには、単に配列の中に配列を入れようとしても、

@x = ("A", "B", "C");
@y = ("D", "E", "F");
@a = (@x, @y); # @b = ("A", "B", "C", "D", "E", "F")

うまくいきません。これでは@xと@yが展開され、単なる配列(一次元配列)になってしまいます。正しくは次のようにします。

@x = ("A", "B", "C");
@y = ("A", "B", "C");
@a = (\@x, \@y);
 
print $a[0][0]; # A
print $a[0][1]; # B
print $a[0][2]; # C
 
print $a[1][0]; # D
print $a[1][1]; # E
print $a[1][2]; # F

\@xのように、配列のシジル「@」の前に「\」を付けます。$a[0][0]とは、@aの0番目の要素 (\@x) の0番目の要素 ("A") を表します。このようにして多次元配列を生成し、多次元配列の要素にアクセスすることができます。

最初に示した例では、@xや@yが("A", "B", "C")のように展開されてしまったため、うまくいきませんでした。

@x = ("A", "B", "C");
print @x; # ("A", "B", "C");

多次元配列のようなものを作るためには、「\@x」として、「@x」という配列自体を指し示す必要があります。これは""でクォートされた文字列の中で、「"」という文字そのものを表すのに「\"」とするのと似ています。

[編集] リファレンス

リファレンスとは、あるデータが格納されている場所を指し示すデータ型です。データに「\」を前置して生成します。

$a = 42;
$b = \$a;

このとき、$bには$aのリファレンスが代入されます。

$a = 42;
$b = \$a;
print $b;

$bを出力すると、

SCALAR(0x9d3e198)

このように表示されます。SCALARというのは、$aのデータ型がスカラであることを表しています。(0x9d3e198)は、$aが格納されている場所(メモリアドレス)を表しています。なお、0x9d3e198という数値は環境によって異なります。

$bから$aの値を取り出すには、$bに$aのデータ型であるスカラのシジル「$」を前置します。

$a = 42;
$b = \$a;
print $$b; # 42

さて、$bには$aのメモリアドレスが入っているということは、$aの値が変わっても、$bは常に$aの値を参照することができるのです。次の例をご覧ください。

$a = 42;
$b = \$a;
$a = 10000;
print $$b; # 10000

これがリファレンスというものです。

$bに代入されたのは42や10000という数値そのものではなく、それらを保持している$aという変数の番地です。$$bは常に「そのとき$aに入っているもの」を表します。

スカラだけでなく、様々なデータ型のリファレンスを生成することができます。

\42; # スカラのリファレンス
\$x; # スカラのリファレンス
\@x; # 配列のリファレンス
\%x; # ハッシュのリファレンス
\&x; # サブルーチンのリファレンス
\*x; # 型グロブのリファレンス
\\$x; # スカラのリファレンスのリファレンス

「\」はリファレンスを生成するための単項演算子です。リファレンスそのものはスカラの一種です。

「$」や「@」のようなシジルを前置してリファレンスから元のデータを取り出すことを、デリファレンスするといいます。

リファレンスはC言語のポインタに似ていますが、より抽象的で安全だとされています。

リファレンスを使うのは、配列の配列などの複雑なデータ構造を扱う場合や、オブジェクトを扱う場合、サブルーチンに参照渡しを行う場合などに限られます。通常の配列やハッシュを使えば済む場面で、リファレンスを使うことはありません。

データを百科事典の記事の内容だとすれば、リファレンスはその記事が「何ページ目にあるか」に当たります。

[編集] スカラのリファレンス

$x = \42;
print ${ $x }; # 42
print $$x; # 42
 
$y = \$x; # \\42
print ${ ${ $y } }; # 42
print $$$y; # 42

[編集] 配列のリファレンス

@x = ("A", "B", "C");
$a = \@x;
print @$a; # ABC

回りくどいことをしなくても、要素を()の代わりに[]で囲むと、直接配列のリファレンスを生成することができます。

$a = ["A", "B", "C"];
print @$a; # ABC

配列のリファレンスの要素にアクセスするには、->を使います。

$a = ["A", "B", "C"];
print $a->[0]; # A

->を付けないと普通の配列として扱われてしまうため、->を付ける必要があります。ただし、

$a = ["A", ["B"], "C"];
print $a->[1]->[0]; # B
print $a->[1][0];

最初の->以外は省略することができます。なぜならば、省略しても他の文法とぶつかることがないからです。

->を使わない方法もあります。

$a = ["A"];
print $a->[0]; # A
print ${ $a }[0]; # A
print $$a[0]; # A

配列の要素はスカラなので、$aに$を前置するのです。$$a[0]は${ $a[0] }ではなく、${ $a }[0]という意味です。

多次元配列でも同様です。

$a = [["A"]];
print $a->[0][0]; # A
print ${ $a }[0][0]; # A
print $$a[0][0]; # A

どちらを用いても構いませんが、${ $a[0] }[0]と$a[0][0]では後者のほうが見やすいとされることもあります。また変数展開コンテキストの中では、$a->[0][0]ではなく$$a[0][0]と書かなければなりません。

[編集] ハッシュのリファレンス

ハッシュのリファレンスを生成するには、次のようにします。

%a = ( a => "Apple" );
$a = \%a;
print %$a; # aApple

要素を{}で囲むことで、直接ハッシュのリファレンスを生成することができます。

$a = { a => Apple };
print %$a; # aApple

%$aは通常のハッシュと同じように扱うことができます。ハッシュの値にアクセスするには、次のようにします。

$a = { a => "Apple" };
print $a->{a}; # Apple
print ${ $a }{a}; # Apple
print $$a{a}; # Apple

$a->{a}->{a}は$a->{a}{a}と書くことができます。

[編集] オブジェクト指向におけるリファレンス

Perl/ライブラリ・モジュールとオブジェクト指向の項で扱います。

このページ「Perl/リファレンス」は、書きかけです。加筆・訂正など、協力いただける皆様の編集を心からお待ちしております。また、ご意見などがありましたら、お気軽にノートへどうぞ。
ヘルプ