我有一个文件revs.pm
:
my %vers = ( foo => "bar" );
另一个文件如importer.pl
:
use revs;
如何从%vers
访问importer.pl
?
答案 0 :(得分:13)
# 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";
答案 1 :(得分:9)
另一种传统方法是使用Exporter中的package模块,然后导出变量:
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);
一个缺点是您必须确保您的变量名称是唯一的,以避免名称冲突。
答案 2 :(得分:6)
或者,你可以不用你的程序部分程序 全局变量。考虑在一个模块中使用此哈希时会发生什么:
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的实现,你的其余部分 程序不关心。