我有很多带有常见配置的小型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模块。
请指出我对此任务的良好解决方案。
答案 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的计数。请注意,我更改了循环中的变量,因此我可以看到它发生了变化并正确重置。