リファレンス(2) 簡単な使い方

値のリファレンスを作成する(値をリファレンスする)には、値の頭に「\」(ASCII環境だとバックスラッシュ、日本語環境だと円マーク)を付けるだけです。

my $ref1 = \$a;     # $ref1$a のリファレンス
my $ref2 = \@b;     # $ref2@b のリファレンス
my $ref3 = \%c;     # $ref3%c のリファレンス
my $ref4 = \123;    # $ref4 は数値 123 のリファレンス
my $ref5 = \"abc";  # $ref5 は文字列 "abc" のリファレンス
my $ref6 = \$ref1;  # $ref6 はリファレンス $ref1 のリファレンス 

そして、リファレンスから値を求める(デリファレンスする)にはリファレンスの頭に「$」「@」「%」「&」など、参照している値の型に沿った記号をつけるだけです。

$$ref1  @$ref2  %$ref3
$$ref4  $$ref5  $$$ref6

(記号を付ければ付けた分だけデリファレンスされます)
リファレンスを使ってコードを書いてみます。

# ref1.pl
my $msg = "Hello, reference world!";
my @arr = ("This", "is", "a", "referred", "array!");
 
my $msgref = \$msg;
my $arrref = \@arr;
 
print "$msgref\n";
print "$$msgref\n";
 
print "$arrref\n";
print "@$arrref\n";
print "$$arrref[4]\n";

まず、スカラー変数 $msg と配列変数 @arr を作成し、それぞれリファレンス $msgref と $arrref を作成します。
$msg に関してはリファレンスを直接表示した場合と、デリファレンスして表示した場合の二つを試しています。
@arr は上記二つに加え、デリファレンスした配列に添え字を付けて要素を表示してみました。
以下が実行結果です。

SCALAR(0x28562c)
Hello, reference world!
ARRAY(0x286364)
This is a referred array!
array!

どうやらリファレンスを直接 print すると、「参照している値の種類」と「値のアドレス(のようなもの)」が表示されましたね。
デリファレンスしたものについては、値がちゃんと表示されています。配列の添え字記法もちゃんと使えました。
ラクダ本には、添え字よりもデリファレンスの方が先に実行されると書いてありました。つまり「$$arrref[4]」は、まずリファレンス $arrref をデリファレンスして配列を求めてから、その配列の4番目のスカラー要素を得ている事になります。
逆に、リファレンスが配列の要素として使われていて、それをデリファレンスしたい場合、{ } を使います。

# ref2.pl
my @arr = \("aaa", "bbb", "ccc");
print ${$arr[0]};

実行結果です。

aaa

\("aaa", "bbb", "ccc") という表現ですが、これは (\"aaa", \"bbb", \"ccc") という表現と同じ意味です。つまり、@arr は「文字列へのリファレンス」の配列です。けっして「配列へのリファレンス」ではありません。なので、$arr[0] と書けば "aaa" に対するリファレンスが得られる事になるはずです。これをデリファレンスすれば "aaa" という値が得られます。
でも単に $$arr[0] と書くと、$arr が「配列へのリファレンス」として解釈されてしまいます。そこで { } を使えば、先に添え字を解決してからデリファレンスする事ができます。
配列の添え字を例にしましたが、ハッシュの添え字についても同じです。
リファレンスはちょっと複雑ですが、じっくり考えればちゃんと理解できました。(^_^) むしろ、C言語のポインタなどに比べれば、とてもシンプルでわかりやすいと感じます。それでいて便利です。すごい。