他の人が言及しているように、クックブックは「適切な」という用語を使用して、より高い字句スコープからの変数を運ぶサブルーチンが作成され、この変数に他の手段で到達できなくなるという事実を指します。クロージャのこの部分を覚えておくために、過度に単純化されたニーモニック「$color
変数へのアクセスは「クローズ」されています」を使用します。
「typeglobsは字句変数に対して定義できません」というステートメントは、typeglobsに関するいくつかの重要なポイントを誤解しています。「「my」を使用してタイプグロブを作成することはできません」と読んだのは、いくぶん真実です。次のことを考慮してください。
my *red = sub { 'this is red' };
これは、「my」キーワードを使用してtypeglobを定義しようとしているため、「my*red」付近の構文エラーで終了します。
ただし、例のコードはこれを実行しようとはしていません。オーバーライドされない限りグローバルであるtypeglobを定義しています。字句変数の値を使用して、typeglobの名前を定義しています。
ちなみに、typeglobは字句的にローカルにすることができます。次のことを考慮してください。
my $color = 'red';
# create sub with the name "main::$color". Specifically "main:red"
*$color = sub { $color };
# preserve the sub we just created by storing a hard reference to it.
my $global_sub = \&$color;
{
# create a lexically local sub with the name "main::$color".
# this overrides "main::red" until this block ends
local *$color = sub { "local $color" };
# use our local version via a symbolic reference.
# perl uses the value of the variable to find a
# subroutine by name ("red") and executes it
print &$color(), "\n";
# use the global version in this scope via hard reference.
# perl executes the value of the variable which is a CODE
# reference.
print &$global_sub(), "\n";
# at the end of this block "main::red" goes back to being what
# it was before we overrode it.
}
# use the global version by symbolic reference
print &$color(), "\n";
これは合法であり、出力は次のようになります
local red
red
red
警告の下で、これは「サブルーチンmain::redredefined」と文句を言います。