我正在使用EV模块创建一个定时事件,该事件将在定义的时间间隔内无限期运行,这是我的定义间隔代码。
#!/usr/bin/perl
use strict;
use warnings qw/ all FATAL /;
use feature 'say';
use EV;
use Time::Piece 'localtime';
my $one_sec = EV::timer 1,1, sub {
say "(1s) Periodic event at ", localtime(EV::now)->hms;
};
my $five_sec = EV::timer 5, 5, sub {
say "(5s) Periodic event at ", localtime(EV::now)->hms;
};
EV::run;
我试图从散列引用中动态定义这些函数,通过循环来创建这些函数。
my $hash = {
'one_sec' => '1',
'five_sec' => '5',
};
我用foreach循环遍历散列。
foreach my $key ( keys %$hash )
{
my $key = EV::timer $hash->{$key},$hash->{$key}, sub {
say "($hash->{$key}) Periodic event at ", localtime(EV::now)->hms;
};
EV::run;
}
它是有效的,但只适用于第一次迭代,我不确定为什么?
非常感谢您的想法。
以下代码未经过测试。
你的代码有两个错误:
首先,在foreach
循环的主体中启动事件循环,这将使它在foreach
的第一次迭代中运行。然后它会被卡在那里,并且只会创建一个计时器。要解决此问题,需要将EV::run
移动到foreach
之外。
然而,它将不会做任何事情。这是因为事件循环没有任何作用。这是因为您在foreach
的主体中用词法定义EV::timer
对象。一旦完成一次迭代,该变量($key
)将超出范围,破坏计时器对象。当创建完这两者后,它将只运行一个空的事件循环。除此之外,您还重新定义了$key
,它已经是散列中的"one_sec"
或"five_sec"
字符串。
相反,您也需要将事件对象放在循环之外的某个地方(因为当您使用my
时,每个块都会在Perl中创建一个词法范围,这是一个特性)。
你还应该使用更能说话的变量名,这样你就不会感到困惑。
#!/usr/bin/perl
use strict;
use warnings qw/ all FATAL /;
use feature 'say';
use EV;
use Time::Piece 'localtime';
my $config = { # was $hash
'one_sec' => '1',
'five_sec' => '5',
}
my $timers;
foreach my $key ( keys %$config ) {
$timers->{$key} = EV::timer $config->{$key},$config->{$key}, sub {
say "($config->{$key}) Periodic event at ", localtime(EV::now)->hms;
};
}
EV::run;