いつパッケージ変数とレキシカル変数を使用する必要がありますか(そして違いは何ですか)?
質問
プログラミングを理解するために、 Perl Monks にある古いPerlコードを探しています。 Win32 :: OLEおよびMS Wordで。コード全体に散らばっているのは、 $ MS :: Word などの名前の変数で、宣言に「 my 」は含まれていません。 Googleを少し読んだ後、これらは「パッケージ変数」と呼ばれ、「 my を使用して宣言された「字句変数」と呼ばれることを理解しています。
最初の質問は、「パッケージ変数は何に適していますか」です。私は(考えて)字句変数とは何かを理解していますが、パッケージ変数の目的やその使用が字句とどのように異なるか理解していないので、2番目の質問は「字句変数とパッケージ変数の違いは何ですか? '
解決
パッケージ変数はシンボルテーブルに存在するため、名前を指定すると、他のパッケージまたはスコープから読み取りまたは変更することができます。字句変数のスコープは、プログラムテキストによって決まります。セクション" Private Variables via my()" perlsubのマンページでは、字句の定義に関する詳細が提供されています。
次の MyModule.pm
があるとします:
package MyModule;
# these are package variables
our $Name;
$MyModule::calls = "I do not think it means what you think it means.";
# this is a lexical variable
my $calls = 0;
sub say_hello {
++$calls;
print "Hello, $Name!\n";
}
sub num_greetings {
$calls;
}
1;
パッケージ $ calls
およびレキシカル $ calls
が含まれていることに注意してください。誰でも前者にアクセスできますが、モジュールは後者へのアクセスを制御します:
#! /usr/bin/perl
use warnings;
use strict;
use MyModule;
foreach my $name (qw/ Larry Curly Moe Shemp /) {
$MyModule::Name = $name;
MyModule::say_hello;
}
print MyModule::num_greetings, "\n";
print "calls = $MyModule::calls\n";
プログラムの出力は
Hello, Larry!
Hello, Curly!
Hello, Moe!
Hello, Shemp!
4
calls = I do not think it means what you think it means.
ご覧のとおり、パッケージ変数はグローバルなので、通常の落とし穴やアドバイスはすべて適用されます。明示的にアクセスを提供しない限り、MyModuleパッケージ外のコードがそのレキシカルな $ calls
にアクセスすることは不可能です。
経験則では、ほとんど常に語彙を使用したいということです。 Damian Conwayによる Perlのベストプラクティス は直接的です:" 決してしない変数をモジュールのインターフェースの一部にする" (オリジナルの強調)。
他のヒント
MJDのスコープの適用を読む必要があります。
perldoc perlmod も参考になります。
コードはこの世のものではありません。作者が$ author :: emailがクールだと思っているように見えるため、世界中の懸念なしにあらゆる種類の名前空間を踏みつけています。
より良い方法は、ハッシュを使用することです。
my %author = (
email => 'author@example.com',
...
);
シンボルテーブル全体をトランキングする必要はありません。
いくつかの Win32 :: OLE
の例があります: http:// www.unur.com/comp/ は芸術作品ではありませんが、このスタイルは改善されていると思います。 PerlとWord VBAでWord文書のページ数が異なるのはなぜですか
少しります:
@pgm::runtime_args = @ARGV ;
したがって、標準の @ARGV
配列を放棄して、 pgm
名前空間を踏みにじります。それだけでなく、すべてのPerlプログラマーは @ARGV
が何であるかを知っています。いずれの場合でも、 @pgm :: runtime_args
はスクリプトで再び使用されません。
$pgm::maxargs = $#pgm::runtime_args + 1 ;
もちろん、スカラーコンテキストの @pgm :: runtime_args
は、その配列の要素数を示します。 $ pgm :: maxargs
が必要な理由はわかりませんが、必要であれば、この行は次のようになっているはずです:
$pgm::maxargs = @pgm::runtime_args;
これ以上のことを引用するつもりはありません。 CobolプログラマーがPerlを作成しようとすると、これが起こると思います。
$program::copyright = "Copyright (c) 02002 - Kenneth Tomiak : All rights reserved.";
年に5桁を割り当ててくれてうれしいです。わからない!
PS:私の抜粋はフェアユースを構成していると思います。
パッケージ変数はグローバル変数です。プログラム全体(他のモジュールも含む)のどこにでも表示されます。そのレベルの可視性や外部の影響が必要または必要な場合に便利です。たとえば、Text :: Wrapモジュールはこれらを使用して、テキストを折り返す列の数に対して単一の構成ポイントを許可します。さらに、パッケージ変数を使用すると、「動的スコープ」と呼ばれるものを使用できます。 -しかし、それはやや高度で少し難解な概念です。
2番目の質問については、 Perlでの私と私たちの違いは何ですか