在 Perl 中,如何从库导入哈希?

发布于 2024-08-23 13:11:46 字数 240 浏览 8 评论 0原文

我有一个文件 revs.pm

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

另一个文件如 importer.pl

use revs;

如何从 importer.pl 访问 %vers

I have a file revs.pm:

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

And another file like importer.pl:

use revs;

How can I access %vers from importer.pl ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清晨说晚安 2024-08-30 13:11:46

创建适当的模块并将 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";

Create a proper module and change the my keyword to our:

# 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";
任谁 2024-08-30 13:11:46

另一种传统方法是在 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);

一个缺点是您必须确保变量名称是唯一的,以避免名称冲突。

Another conventional way is to use the Exporter module in your package, and export the variable:

package revs;
use strict;
use warnings;
require Exporter;
our @ISA    = qw(Exporter);
our @EXPORT = qw(%vers);
our %vers   = (foo=>'bar');
1;

This avoids having to use the package name when referring to the variable from importer.pl:

use strict;
use warnings;
use Data::Dumper;
use revs;
print Dumper(\%vers);

One disadvantage is that you must make sure your variable name is unique in order to avoid name collisions.

李不 2024-08-30 13:11:46

或者,您可以不将程序的某些部分与
全局变量。考虑一下当您在一个模块中使用此哈希时会发生什么:

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 会产生不同的结果
每次调用时都会得到结果。祝调试愉快。 (这是
更多的是每个问题而不是全局状态问题;但通过暴露
在内部实现中,您允许调用者执行以下操作
你不是故意的,这很容易破坏你的程序。)

当你改变硬编码时,重写 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 的实现,其余的
程序不会关心。

Alternatively, you could just not couple parts of your program with a
global variable. Consider what happens when you use this hash in one module:

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;
    }
}

And then in some other module:

package Bar;
use MyApp::Versions qw(%versions);

some_other_function {
    while(my ($k, $v) = each %versions){
       print "$k => $v\n";
    }
}

And then use both modules:

use Foo;
use Bar;

some_other_function;
some_function;
some_other_function;

Depending on $some_condition, some_other_function produces different
results each time you call it. Have fun debugging that. (This is
more of an each problem than a global state problem; but by exposing
the internal implementation, you allow your callers to do things that
you didn't intend, and that can easily break your program.)

It's also a pain to rewrite Foo and Bar when you change the hard-coded
hash to an on-demand database lookup, for example.

So the real solution is to design a proper API, and export that
instead of the entire variable:

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;

Now your module is easier to use:

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;
}

Now some_function can't mess up some_other_function, and when you
change the implementation of get_component_version, the rest of your
program won't care.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文