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

标签 perl

我正在尝试将我的代码中的一些 use 语句切换为 require 模块,我只在满足某些条件时使用(例如,程序可能被加载 1,000 次在需要这些模块的时间之间),以降低开销并提高程序的执行速度(我一直在使用 Devel::NYTProf 来分析我的代码,一些模块增加了显着的执行时间,即使我没有在特定 session 中使用它们)。

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

sub dataDumper {
    require Data::Dumper;
    Data::Dumper->import;
    say STDERR Dumper @_;
}

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

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

最佳答案

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

say STDERR Dumper(@_);

请注意,您以这种方式加载的潜艇原型(prototype)将被忽略。


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

$ 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

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


Am I losing any sort of optimizations by not loading these modules at compile time?

常量需要替换为无法折叠的较慢的函数调用。

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

关于perl - 如何动态加载 Perl 模块并使用它们的功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66858247/

相关文章:

perl - 如何处理 Moose 中的模拟角色?

Perl、ClamAV、扫描流中的病毒

perl - 一台服务器的 whois TCP 套接字连接失败

perl - 在Perl中使用无括号的子例程调用的原因是什么?

javascript - 我需要进行 Ajax 调用并显示数据库表的内容,我正在使用 Perl CGI 并尝试通过 javaScript 调用 Perl 脚本

perl - 怎么搭配\'

windows - 在命令提示符下从 PATH 文件夹运行 perl 脚本

perl 在空文件上拆分

perl - 如何在 pod2usage 中指定宽度?

html - Perl 网络抓取工具,从脚本标签内的文本中检索数据