如何动态加载 Perl 模块并使用它们的功能?

Tim*_*ler 2 perl

我正在尝试将use代码中的某些语句切换到require仅在满足某些条件时才使用的模块(例如,在需要这些模块的两次之间程序可能会加载 1,000 次),以降低开销并提高执行速度我的程序(我一直在使用 Devel::NYTProf 来分析我的代码,即使我没有在某个会话中使用它们,一些模块也会增加大量的执行时间)。

我遇到了一个问题,脚本在加载时终止,因为符号未定义(在导入该模块之前不会定义符号)。有没有办法告诉 Perl 符号将在运行时导入?一个简单的例子:如果我调用一个触发它的例程,我只想使用 Data::Dumper:

sub dataDumper {
    require Data::Dumper;
    Data::Dumper->import;
    say STDERR Dumper @_;
}
Run Code Online (Sandbox Code Playgroud)

但是,调用Dumper第三行会导致异常。我可以通过参考来解决这个问题Data::Dumper->Dump。然而,LWP::UserAgent 的一个类似问题证明有点贴纸,因为 LWP::UserAgent 导入 HTTP::Request。我还没有想出my $request = new HTTP::Request GET => $params->{'url'};避免抛出异常的变体。

假设我可以这样做,有什么理由说明这种方法是个坏主意吗?通过在编译时不加载这些模块,我是否会失去任何类型的优化?在像 LWP 这样的模块上,这似乎是一个简单的调用——我只是不怎么使用它。我对是否尝试在(例如) Text::Textile 和 Text::MultiMarkdown 之间动态切换感到有些困惑(我通常每次执行只需要一个。

ike*_*ami 5

在 sub 调用中,只能为声明的 sub 省略参数周围的括号。

say STDERR Dumper(@_);
Run Code Online (Sandbox Code Playgroud)

请注意,您以这种方式加载的 subs 上的原型将被忽略。


第二行没有问题,因为它不涉及子调用。方法调用不受影响。

$ perl -M5.010 -e'
   if ($ARGV[0]) {
      require LWP::UserAgent;   # or HTTP::Request
      my $request = new HTTP::Request GET => "https://stackoverflow.com";
   }

   say "ok";
' 0
ok

$ perl -M5.010 -e'
   if ($ARGV[0]) {
      require LWP::UserAgent;   # or HTTP::Request
      my $request = new HTTP::Request GET => "https://stackoverflow.com";
   }

   say "ok";
' 1
ok
Run Code Online (Sandbox Code Playgroud)

因此,类模块在这里特别有用。考虑复杂情况下的插件模型。


通过在编译时不加载这些模块,我是否会失去任何类型的优化?

常量需要替换不能折叠的较慢的函数调用。

$ perl -MO=Concise,-exec -M5.010 -e'
   use constant FOO => 2;
   say 2 + FOO;
'
...
2  <;> nextstate(main 188 -e:3) v:{,fea=1
3  <0> pushmark s
4  <$> const[IV 4] s/FOLD
5  <@> say vK
...
Run Code Online (Sandbox Code Playgroud)
$ perl -MO=Concise,-exec -M5.010 -e'
   say 2 + FOO();
   require constant; import constant FOO => 2;
'
...
2  <;> nextstate(main 2 -e:2) v:{,fea=1
3  <0> pushmark s
4  <$> const[IV 2] s
5  <0> pushmark s
6  <#> gv[*FOO] s/EARLYCV
7  <1> entersub[t2] sKS/TARG
8  <2> add[t3] sK/2
9  <@> say vK
...
Run Code Online (Sandbox Code Playgroud)