程序启动后确定加载的模块

时间:2014-05-05 20:17:32

标签: perl module perl-module

我有一个分叉服务器。我在fork之前加载所有模块。

......或者我呢?我希望在程序中的某个点之后加载的每个模块都将一条消息记录到STDERR。

我打算使用以下内容,但它记录了使用do执行的一些脚本。

my %ignore = map { $_ => 1 } ( ... );
unshift @INC, sub {
   my (undef, $path) = @_;
   warn("$path wasn't loaded before forking.\n")
      if !$ignore{$path};

   return ();
};

我并非出于想法,但在我花费更多时间之前,我想知道是否有现有的解决方案。

2 个答案:

答案 0 :(得分:4)

使用do的内容是什么?只是

if $path =~ /\.pm\z/ && !$ignore{$path};

足以区分?

其他选择:

使用PPI进行静态代码分析(使用或基于Module::Extract::Use)。

根据SIGHUP或其他信号将%INC转储到文件中。

答案 1 :(得分:0)

解决方案:

my $old_require =
   defined(&CORE::GLOBAL::require)
      ? \&CORE::GLOBAL::require
      : sub { CORE::require($_[0]) };

my $new_require = sub {
   my $path = shift;
   if ($INC{$path}) {
      return $old_require->($path);
   }

   my $rv = $old_require->($path);
   warn("Loaded $path after fork\n");
   return $rv;
};

no warnings 'redefine';
*CORE::GLOBAL::require = $new_require;

该解决方案具有以下功能:

  • 记录require EXPR
  • 加载的模块
  • 记录require BAREWORD
  • 加载的模块
  • 记录use BAREWORD
  • 加载的模块
  • 忽略由do EXPR加载的代码。
  • 忽略无法加载的模块。
  • 忽略已加载的模块。
  • 即使操作@INC也可以使用。

最后四个是OP中解决方案遇到的问题。我无法找到解决方案的任何缺点。