シンボリックリファレンス
一昨日の日記でリファレンスには「ハードリファレンス」と「シンボリックリファレンス」という2種類がある、と書きました。今まで扱っていたのはハードリファレンスの方です。
シンボリックリファレンスといっても中身は単純な文字列で、文字列をデリファレンスすると、その文字列が指す名前の変数を参照する事ができる、という機能の事です。さりげなく書きましたがかなり便利な機能ですね。
ただし、シンボリックリファレンスが参照できるのはパッケージ変数(our)だけです。レキシカル変数(my)は参照できません。これは、パッケージ変数はパッケージのシンボルテーブル(変数名などの表)に登録されるのに対し、レキシカル変数は登録されない事によるものです。シンボリックリファレンスはシンボルテーブルから変数の実体を探すわけですね。(^_^)
早速使ってみます。
# ref7.pl
our $apple = "red and sweet!";
our $orange = "orange and sweet!";
our $lemon = "yellow and sour!";
my $fruit = "apple";
print "$fruit\n"; # 変数名
print "$$fruit\n"; # デリファレンス
print "$fruit is $$fruit\n";
$fruit = "lemon"; # 変数名を変えてみる
print "$fruit is $$fruit\n";
$fruit = "orange";
print "$fruit is $$fruit\n";
まず、$apple、$orange、$lemon というパッケージ変数を宣言します。そして、$fruit に変数名を代入しています。これはもちろんただの文字列ですが、デリファレンス(頭に記号を付けたり矢印演算子を使ったり)する事で、シンボルから参照できるわけです。
実行結果です。
apple red and sweet! apple is red and sweet! lemon is yellow and sour! orange is orange and sweet!
ちゃんと参照できていますね。(^_^)
ただ、文字列をデリファレンスするだけで参照できてしまうのは、便利ですが危険でもあります。ラクダ本によると、シンボリックリファレンスの乱発を防ぐ為にはプログラムの先頭に
use strict 'refs';
と書けばいいそうです。use は package を勉強した時に一緒に勉強しましたが、この場合 strict は「プラグマ」と呼ばれる「Perlコンパイラへの指示」だそうです。これについては、また詳しく勉強します。
試しに先ほどのプログラムの先頭に use strict 'refs'; と書いて実行してみると……
apple Can't use string ("apple") as a SCALAR ref while "strict refs" in use at ref7.pl line 10.
ちゃんとエラーが出てくれました。(^_^)