私はファイルを持っていますrevs.pm
:
my %vers = ( foo => "bar" );
そして次のような別のファイルimporter.pl
:
use revs;
%vers
からアクセスするにはどうすればよいimporter.pl
ですか?
私はファイルを持っていますrevs.pm
:
my %vers = ( foo => "bar" );
そして次のような別のファイルimporter.pl
:
use revs;
%vers
からアクセスするにはどうすればよいimporter.pl
ですか?
もう1つの従来の方法は、パッケージでExporterモジュールを使用し、変数をエクスポートすることです。
package revs;
use strict;
use warnings;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(%vers);
our %vers = (foo=>'bar');
1;
これにより、次の変数を参照するときにパッケージ名を使用する必要がなくなりますimporter.pl
。
use strict;
use warnings;
use Data::Dumper;
use revs;
print Dumper(\%vers);
1つの欠点は、名前の衝突を回避するために、変数名が一意であることを確認する必要があることです。
または、プログラムの一部をグローバル変数と結合することはできません。このハッシュを1つのモジュールで使用するとどうなるかを考えてみましょう。
package Foo;
use MyApp::Versions qw(%versions); # i'm going to pretend that you didn't call the module "revs".
some_function {
while(my ($k, $v) = each %versions){
return if $some_condition;
}
}
そして、他のモジュールで:
package Bar;
use MyApp::Versions qw(%versions);
some_other_function {
while(my ($k, $v) = each %versions){
print "$k => $v\n";
}
}
次に、両方のモジュールを使用します。
use Foo;
use Bar;
some_other_function;
some_function;
some_other_function;
に応じて$some_condition
、some_other_functionは呼び出すたびに異なる結果を生成します。それをデバッグして楽しんでください。(これはeach
グローバルな状態の問題というよりも問題ですが、内部実装を公開することで、呼び出し元が意図しないことを実行できるようになり、プログラムが簡単に破損する可能性があります。)
たとえば、ハードコードされたハッシュをオンデマンドのデータベースルックアップに変更する場合、FooとBarを書き直すのも面倒です。
したがって、実際の解決策は、適切なAPIを設計し、変数全体ではなくそれをエクスポートすることです。
package MyApp::Versions;
use strict;
use Carp qw(confess);
use Sub::Exporter -setup => {
exports => ['get_component_version'],
};
my %component_versions = ( foo => 42 ); # yes, "my", not "our".
sub get_component_version {
my ($component) = @_;
return $component_versions{$component} ||
confess "No component $component!"
}
1;
これで、モジュールが使いやすくなりました。
package Foo;
use MyApp::Versions qw(get_component_version);
sub some_function {
die 'your foo is too old'
unless get_component_version('foo') >= 69;
return FooComponent->oh_hai;
}
これで、some_functionはsome_other_functionを台無しにすることができなくなり、get_component_versionの実装を変更しても、プログラムの残りの部分は気になりません。