メメメモモ

プログラミング、筋トレ、ゲーム、etc

シンボルテーブルについて

perlには、シンボルテーブルというものがあります。
このテーブルには、パッケージ名やサブルーチン名などが格納されています。
perlコンパイラが参照するためにシンボルテーブルがあるのです。


シンボルテーブルは、パッケージ毎に存在します。
例えば、
mainパッケージには、「%main::」という名前のシンボルテーブルがあります。
Testパッケージには、「%Test::」という名前のシンボルテーブルがあります。
各シンボルテーブルには、パッケージの内容(変数名、関数名など)が格納されています。


シンボルテーブルの内容は、下記のように、プログラムから参照できます。

foreach $symname (sort keys %main::) {
   local *sym = $main::{$symname};
   print "\$$symname is defined\n" if defined $sym;
   print "\@$symname is defined\n" if               @sym;
   print "\%$symname is defined\n" if                %sym;
}


表示結果は、下記のような感じでずらずらと出力されます。

...
$" is defined
$$ is defined
$/ is defined
$0 is defined
$@ is defined
%CORE:: is nonnull
%Carp:: is nonnull
%DB:: is nonnull
%DynaLoader:: is nonnull
%ENV is nonnull
@INC is nonnull
%INC is nonnull
%IO:: is nonnull
...


シンボルテーブルへのアクセ鵜には、型グロブを通して行なえます。
例えば、下記のような感じで、代入が行なえます。

# エイリアス処理($aと$test、%aと%testなどが同じ変数になる)
*main::a = *main::test;

# test関数を定義
*main::test = sub { return "test"; };

# main::testをTestパッケージにインポート
*Test::test = \&main::test;

abbreviationモジュール


http://search.cpan.org/~miyagawa/abbreviation-0.02/lib/abbreviation.pm


こちらのモジュールは、モジュール名を省略形で表せるようにするものです。
例えば「Foo::Bar::Baz」は「F::B::Baz」で表せるようになります。

use abbreviation qw(Foo::Bar::Baz);
  
my $obj = Foo::Bar::Baz->new;
my $obj = F::B::Baz->new;        # same


これを実現するために、シンボルテーブルの操作が行なわれています。
つまり、

 *{'F::B::Baz::'} = *{'Foo::Bar::Baz::'};

としている訳です。


ってことで、シンボルテーブルを復習したのは、このモジュールの仕組みを調べるためでしたとさ。