开发者

How can I conditionally use a module in Perl?

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* .

开发者_StackOverflow社区

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?


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


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


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

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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜