3

私はファイルを持っていますrevs.pm

my %vers = ( foo => "bar" );

そして次のような別のファイルimporter.pl

use revs;

%versからアクセスするにはどうすればよいimporter.plですか?

4

3 に答える 3

13

適切なモジュールを作成し、myキーワードを次のように変更します

# revs.pm
package revs;

our %vers = ( foo => "bar" );

1; # Perl modules need to return a boolean "true" value.

# importer.pl
use revs;

print $revs::vers{foo} . "\n";
于 2010-03-04T01:58:08.530 に答える
9

もう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つの欠点は、名前の衝突を回避するために、変数名が一意であることを確認する必要があることです。

于 2010-03-04T02:19:46.287 に答える
6

または、プログラムの一部をグローバル変数と結合することはできません。このハッシュを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の実装を変更しても、プログラムの残りの部分は気になりません。

于 2010-03-04T09:34:41.630 に答える