範囲内
Perl には、グローバルとレキシカルという 2 つの変数名スコープ メカニズムがあります。レキシカル var の宣言は で行われmy
、閉じ中括弧に遭遇するまで、この名前でアクセス可能です。
一方、グローバル変数はどこからでもアクセスでき、スコープはありません。これらは and で宣言できますがour
、が有効でないuse vars
場合は宣言する必要strict
はありません。ただし、名前空間、またはpackages
. 名前空間は、変数名から 2 つのコロン (または単一引用符、ただし絶対に使用しないでください) で区切られた接頭辞です。変数のパッケージ内では、プレフィックスの有無にかかわらず、変数にアクセスできます。パッケージの外では、プレフィックスが必要です。
このlocal
関数はやや特殊で、グローバル変数に一時的な値を与えます。この値のスコープは、レキシカル変数のスコープに、このスコープ内で呼び出されるすべてのサブルーチンのスコープを加えたものと同じです。このスコープを終了すると、古い値が復元されます。これを動的スコープと呼びます。
グロブ上
Perl は、名前空間とすべての変数名 ( stashと呼ばれることもあります) を表す大きなハッシュでグローバル変数を編成します。このハッシュの各スロットには、いわゆるグロブがあります。型グロブは、スカラー、配列、ハッシュ、IO、フォーマット、コードなど、Perls の各ネイティブ型のフィールドを持つ特別なハッシュです。追加したい値の参照をグロブに渡すことで、スロットに割り当てます -グロブはそれ自体で適切なスロットを見つけ出します。これは、同じ名前の変数を複数持つことができる理由でもあります ( $thing
、@thing
、%thing
などthing()
)。型グロブには特別な記号、つまりアスタリスクがあります*
。
の上no strict 'refs'
no strict 'refs'
あなたが何をしているのかを知っていれば、それは素晴らしいことです。通常、通常の参照のみを逆参照できます。
my @array = (1 .. 5);
my $arrayref = \@array; # is a reference
push @{$arrayref}, 6; # works
push @{array}, 6; # works; barewords are considered o.k.
push @{"array"}, 6; # dies horribly, if strict refs enabled.
最後の行は文字列を逆参照しようとしましたが、これは悪い習慣と見なされます。ただし、 では、no strict 'refs'
ここで行っているように、コンパイル時に名前がわからない変数にアクセスできます。
結論
関数は、呼び出しコードのパッケージの名前を返します。caller
つまり、1 つの呼び出しスタック フレームを検索します。この名前は、呼び出し元のパッケージの完全な名前$a
と$b
変数を構築するためにここで使用されるため、接頭辞なしで使用できます。次に、これらの名前はlocal
、新しく宣言されたレキシカル変数の参照に割り当てられます。
グローバル変数$a
と$b
は、各パッケージで事前に宣言されています。
ループではforeach
、これらのレキシカルには異なる値が割り当てられます (レキシカル変数はグローバル変数よりも優先されます) が、参照のためにグローバル変数$foo::a
と$foo::$b
同じデータを指すため、呼び出しの匿名コールバック サブルーチンがreduce
2 つの引数を簡単に読み取ることができます。(これについての詳細は、ikegamisの回答を参照してください。)
(a) 効果が外部から見えず、(b) コールバックが面倒な引数のアンパックを行う必要がないため、この面倒なことはすべて良いことです。