如何有条件地使用 Perl 中的模块?

发布于 2024-09-28 08:36:23 字数 403 浏览 2 评论 0原文

我想在 Perl 中做这样的事情:

$Module1="ReportHashFile1"; # ReportHashFile1.pm
$Module2="ReportHashFile2"; # ReportHashFile2.pm

if(Condition1)
{
  use $Module1;
}
elsif(Condition2)
{
  use $Module2;
}

ReportHashFile*.pm 包含一个包 ReportHashFile* 。

另外如何根据动态模块名称引用模块内部的数组?

@Array= @$Module1::Array_inside_module;

无论如何我可以实现这个目标吗?某种编译器指令?

I want to do something like this in Perl:

$Module1="ReportHashFile1"; # ReportHashFile1.pm
$Module2="ReportHashFile2"; # ReportHashFile2.pm

if(Condition1)
{
  use $Module1;
}
elsif(Condition2)
{
  use $Module2;
}

ReportHashFile*.pm contains a package ReportHashFile* .

Also how to reference an array inside module based on dynamic module name?

@Array= @$Module1::Array_inside_module;

Is there anyway I can achieve this. Some sort of compiler directive?

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

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

发布评论

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

评论(4

别想她 2024-10-05 08:36:23

您可能会发现 if 模块对此很有用。

否则,基本思想是使用在运行时发生的 require,而不是在编译时发生的 use。请注意,'

BEGIN {
    my $module = $condition ? $Module1 : $Module2;
    my $file = $module;
    $file =~ s[::][/]g;
    $file .= '.pm';
    require $file;
    $module->import;
}

至于寻址全局变量,如果您只是导出变量或将其返回给调用者的函数,则可能会更容易,您可以通过其非限定名称来使用它。否则,也可以使用方法并将其调用为 $Module->method_name

或者,您可以使用 perlref 中记录的符号引用。然而,这通常是一种代码味道。

my @array = do {
    no strict 'refs';
    @{ ${ "${Module}::Array_inside_module" } };
};

You might find the if module useful for this.

Otherwise the basic idea is to use require, which happens at run-time, instead of use, which happens at compile-time. Note that '

BEGIN {
    my $module = $condition ? $Module1 : $Module2;
    my $file = $module;
    $file =~ s[::][/]g;
    $file .= '.pm';
    require $file;
    $module->import;
}

As for addressing globals, it might be easier if you just exported the variable or a function returning it to the caller, which you could use by its unqualified name. Otherwise there's also the possibility of using a method and calling it as $Module->method_name.

Alternatively, you could use symbolic references as documented in perlref. However, that's usually quite a code smell.

my @array = do {
    no strict 'refs';
    @{ ${ "${Module}::Array_inside_module" } };
};
梦明 2024-10-05 08:36:23

除非执行速度很重要,否则可以使用字符串 eval

if (Condition1) {
    eval "use $Module1"; die $@ if $@;
}
elsif (Condition2) {
    eval "use $Module2"; die $@ if $@;
}

Unless the execution speed is important, you can use string eval:

if (Condition1) {
    eval "use $Module1"; die $@ if $@;
}
elsif (Condition2) {
    eval "use $Module2"; die $@ if $@;
}
回忆追雨的时光 2024-10-05 08:36:23

人们已经告诉过您如何使用 Perl 原语加载模块。还有Module::Load::Conditional

如果您希望访问同名的数组,无论您加载哪个模块,请考虑为此创建一个方法,以便您可以跳过符号引用内容。为每个模块提供一个同名的方法:

package ReportHashFileFoo;
our @some_package_variable;
sub get_array { \@some_package_variable }

然后,当您加载该模块时:

if( ... some condition ... ) {
    eval "use $module" or croak ...;
    my $array_ref = $module->get_array;
    }

2023 update 最近我一直在 state 中使用 require > 表达式,因为这只在范围内发生一次:

use v5.10;

if( ... some condition ... ) {
    state $rc =  require $module;
    my $array_ref = $module->get_array;
    }

我不知道你真正在做什么 (XY 问题),但可能有更好的设计。当事情看起来像这样棘手时,通常是因为您忽略了更好的解决方法。

People have already told you how you can load the module with Perl primitives. There's also Module::Load::Conditional.

If you're looking to access an array of the same name no matter which module you loaded, consider making a method for that so you can skip the symbolic reference stuff. Give each module a method of the same name:

package ReportHashFileFoo;
our @some_package_variable;
sub get_array { \@some_package_variable }

Then, when you load that module:

if( ... some condition ... ) {
    eval "use $module" or croak ...;
    my $array_ref = $module->get_array;
    }

2023 update Lately I've been using require in a state expression since that only happens once in the scope:

use v5.10;

if( ... some condition ... ) {
    state $rc =  require $module;
    my $array_ref = $module->get_array;
    }

I don't know what you're really doing (XY Problem), but there's probably a better design. When things seem tricky like this, it's usually because you're overlooking a better way to to it.

月下伊人醉 2024-10-05 08:36:23

也许有帮助...

调试的小例子。

sub DEBUG () {1};               # It's the condition (may be a debuglevel...)

use if DEBUG, Data::Dumper;     # Conditionally load

my $testvar = "foo";
print "Testing: $testvar\n" if     DEBUG;
print "No testing\n"        unless DEBUG;

print Dumper \$testvar if DEBUG;  # "Dumper" only available if "DEBUG" returns "true".

使用 sub DEBUG () {1}; 输出

Testing: foo
$VAR1 = \'foo';

sub DEBUG () {0};

No testing

qv
perldoc.perl.org/if

Maybe helpful...

A little example for debugging.

sub DEBUG () {1};               # It's the condition (may be a debuglevel...)

use if DEBUG, Data::Dumper;     # Conditionally load

my $testvar = "foo";
print "Testing: $testvar\n" if     DEBUG;
print "No testing\n"        unless DEBUG;

print Dumper \$testvar if DEBUG;  # "Dumper" only available if "DEBUG" returns "true".

Output with sub DEBUG () {1};

Testing: foo
$VAR1 = \'foo';

Output with sub DEBUG () {0};

No testing

q.v.
perldoc.perl.org/if

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