グローバルな名前空間を宣言する
package
は BLOCK を指定の名前空間で宣言します。
パッケージ宣言のスコープは、BLOCK が指定されていれば、そのコードブロックになります。
package Cat {
our $name = '猫';
}
print $Cat::name, "\n"; # 猫
BLOCK が指定されていなければ、その宣言があった箇所から、現在のスコープが終わるまでになります。
つまり、BLOCK がない形式は、現在のスコープの終わりまで有効です。
このスコープという観点では my
, state
,
our
演算子と良く似てます。
{
package Cat;
our $name = '猫';
}
print $Cat::name, "\n"; # 猫
名前空間のスコープ内に未修飾なダイナミックな識別子があれば、それらは該当の名前空間に属します。
ただし、別の package
宣言によって上書きされた識別子や、
STDOUT
, ARGV
, ENV
, そして
$!, $@ といった特殊変数など、main::
に割り当てられている特別な識別子は除きます。
package Cat {
$name = '猫'; # この未修飾な変数は名前空間 Cat の中の変数
}
print $Cat::name, "\n"; # 猫
print $name, "\n"; # エラー!
package
文は local
変数のようなダイナミック変数のみに作用し、
my
, state
,
our
で生成されたレキシカルスコープ変数には作用しません。
これは何を言っているのかというと、package
文によって変数のスコープが終わってしまうのかどうかを指しています。
次のサンプルコードでは、my
によるレキシカルスコープ変数と
local
によるダイナミックスコープ変数を定義しています。
その後に package
文がありますが、ここを境に、レキシカルスコープ変数のスコープは終了しませんが、
ダイナミックスコープ変数のスコープは終了してしまいます。
my $lex = 'abc'; # my によるレキシカルスコープ変数を定義
local $dyn = 'def'; # local によるダイナミックスコープ変数を定義
package Cat;
print $lex, "\n"; # package 文により my のスコープは終わらないため、$lex は有効
print $dyn, "\n"; # package 文により local スコープが終わるため、$dyn は無効となりエラー
通常、package
文は require
や
use
によって組み込まれるファイルの先頭で宣言されます。
しかし、複数の個所でパッケージを切り替えていくこともできます。
これはどういうことかというと、次のように package
文を同じファイル内で何度も登場させることが可能という意味です。
これが可能になるのは、コンパイラーは package
文に遭遇したら、
それ以降のブロックの残りの部分に対してデフォルトのシンボルテーブルを決定しているだけだからです。
{
package Cat;
our $name = '猫';
package Dog;
our $name = '犬';
}
print $Cat::name, "\n"; # 猫
print $Dog::name, "\n"; # 犬
$SomePack::var
や ThatPack::INPUT_HANDOLE
のように、
パッケージ名と二重のコロンを識別子の前に置けば、現在のパッケージ以外のパッケージの中にある識別子を参照することもできます。
もしパッケージ名が省略されたら、main
パッケージが想定されます。
つまり、$::sail
は $main::sail
と同等です
(Perl 4 の古いコードで良く見られる $main'sail
も同等です)。
次のサンプルコードは Cat
というパッケージ(名前空間)に、
スカラー変数 $name
とサブルーチン greet()
が定義されています。
これらを main
から呼び出しています。
package Cat {
our $name = '猫';
sub greet { print "ニャー\n"; }
}
print $Cat::name, "\n"; # 猫
&Cat::greet(); # ニャー
VERSION が指定されると、package
は、指定の名前空間の中の変数 $VERSION
に、
指定の VERSION を表す version
オブジェクトをセットします。
VERSION は version
モジュールで定義されている "strict" スタイルのバージョン番号でなければいけません。
つまり、指数なしの正の 10 進数の数値(整数または小数)、または、'v' で始まり、
少なくとも 3 つの 10 進数数値をドット区切ったバージョン文字列でなければいけません。
package Cat v1.3.0 {
our $name = '猫';
}
package Dog 1.7 {
our $name = '犬';
}
print $Cat::VERSION, "\n"; # v1.3.0
print $Dog::VERSION, "\n"; # 1.7
$VERSION をセットするのはパッケージにつき 1 度だけにするべきでしょう。
前述の通り、package NAMESPACE VERSION BLOCK
構文によって
暗黙的にパッケージ変数 $VERSION が生成され値もセットされます。
一方で、パッケージの中で明示的に $VERSION を宣言することも可能です。
バージョンをセットするのはどちらでも構いませんが、両方を使うことは避けた方が良いでしょう。
package Cat {
our $VERSION = '1.3.0';
our $name = '猫';
}
print $Cat::VERSION, "\n"; # 1.3.0
パッケージ、モジュール、クラスに関しての詳細は perlmod の "Packages" を参照してください。 そのほかのスコープの話題については perlsub を参照してください。