perl においてはパッケージ間で変数が干渉しあわないようにするため、 別々の名前空間を用意している。デフォルトでは、 perl スクリプトは `main' というパッケージにコンパイルされる。
package
宣言を使うと、名前空間を変えることができる。
パッケージ宣言の効く範囲は、宣言から閉じたブロックの最後までである
(local()
宣言子と同じ)。
通常、パッケージ宣言は `require' でインクルードされるファイルの
最初の宣言として使う。
一箇所以上でパッケージを使うことができる。 それは単にブロックの残りに対してコンパイラが使う シンボルテーブルが変わるだけである。
識別子にパッケージ名と '
(シングルクォート)をつけることで、
他のパッケージの変数やファイルハンドルを参照することができる。
パッケージ名がなければ、`main' が使われる。
アルファベットで始まる識別子のみパッケージのシンボルテーブルに格納される。
他のシンボルは `main' パッケージに格納される。
さらに、識別子 STDIN
、STDOUT
、STDERR
、ARGV
、
ARGVOUT
、ENV
、INC
、SIG
は
それ本来の目的以外に使う場合でもパッケージ `main' のままである。
また、`m'、`s'、`y' という名前のパッケージを使うと、 パッケージ名をつけた識別子を使うことはできない。 なぜなら、それぞれパターンマッチ、置換、変換 を表すと解釈されるからである。
eval
される文字列は eval
と同じパッケージにコンパイルされる。
(ただし、$SIG{}
への代入においては、
シグナルハンドラは main
パッケージにあると仮定される。
パッケージ内にシグナルハンドラを作りたい場合は
シグナルハンドラ名にパッケージ名をつけること。)
例としては、perl ライブラリにある perldb.pl
がある。
これは、デバッガがデバッグしようとするスクリプト内の変数を干渉しないように、
最初に DB
パッケージに入る。
そして、いろいろな場合に、
main
パッケージの文脈で expression を評価するために
一時的に main
パッケージに切り変わる。
パッケージのシンボルテーブルは
パッケージ名の前に `_' をつけた名前の連想配列に格納されている。
連想配列の各エントリの値は、
*name
記法を使う際に参照される値と同じである。
実際、次の例は同じ効果がある(もちろん main
パッケージにおいて)が、
一つ目の方が、コンパイル時にシンボルテーブルを探すので、より効率がよい。
local(*foo) = *bar; local($_main{'foo'}) = $_main{'bar'};
これを使って例えばパッケージ内の全変数を出力することができる。
以下に perl ライブラリから dumpvar.pl
を示す。
package dumpvar; sub main'dumpvar { ($package) = @_; local(*stab) = eval("*_$package"); while (($key,$val) = each(%stab)) { { local(*entry) = $val; if (defined $entry) { print "\$$key = '$entry'\n"; } if (defined @entry) { print "\@$key = (\n"; foreach $num ($[ .. $#entry) { print " $num\t'",$entry[$num],"'\n"; } print ")\n"; } if ($key ne "_$package" && defined %entry) { print "\%$key = (\n"; foreach $key (sort keys(%entry)) { print " $key\t'",$entry{$key},"'\n"; } print ")\n"; } } } }
このサブルーチンは dumpvar
パッケージ内にコンパイルされるが、
`main' パッケージにおいてサブルーチン名を使用可能とするために、
サブルーチン名の前にパッケージ名をつけなければならないことに注意。