有什么好方法可以为perl脚本共享可重新加载的配置参数

时间:2013-02-08 06:22:36

标签: perl configuration import daemon signal-handling

我有很多带有常见配置的小型Perl守护进程。

目前,我使用它来加载设置:

在myconfig.pm中:

package MyConfig;
use base 'Exporter';

BEGIN {
    our @EXPORT = qw( $DB_DSN $DB_USER $DB_PWD );
}

our @EXPORT;
use vars @EXPORT;

$DB_DSN = "DBI:mysql:...";
$DB_USER = 'asdad';
...

在daemon.pl中:

use MyConfig;

这很好用。但是现在我有了在收到USR1信号时重新加载配置的新要求。我知道

$SIG{"USR1"} = sub { ... }

但接下来呢?再次use MyConfig?看起来很疯狂。

我的脚本必须在许多不同的平台和不同的perl版本上运行,从5.8到现代,所以我试图避免使用CPAN模块。

请指出我对此任务的良好解决方案。

1 个答案:

答案 0 :(得分:2)

当你use Module (ARGS)时,这相当于

BEGIN {
  require Module;
  Module->import(ARGS);
}

require找到并编译模块。每个模块只发生一次。 import运行特殊的import子,它通常将subs和变量加载到调用者名称空间(由Exporter模块提供)。所以

$SIG{USR1} = sub { no warnings 'redefine'; MyConfig->import };

可能很适合您的问题。


跟进:

我写了这个小程序来证明这是有效的(使用ALRM而不是USR1):

use 5.010;
package Foo;
sub import{ # The Exporter module writes something similar.
  no strict 'refs';
  *{caller()."::var"} = \do{ my$x = 1 }; # put $foo into callers namespace
}

package main;
Foo->import(); # use Foo; if the package were in another file
$SIG{ALRM} = sub{ Foo->import; alarm 10 };
alarm 10;
while(1){
  say $var++;
  sleep 1;
}

输出:一次又一次地从0到大约10的计数。请注意,我更改了循环中的变量,因此我可以看到它发生了变化并正确重置。