我正在使用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;
}
它有效,但仅在第一次迭代时,我不确定为什么会这样?
非常感谢您的想法。
答案 0 :(得分:2)
以下代码未经过测试。
您的代码有两个问题:
首先,您将在foreach
循环的主体中启动事件循环,这将使其在foreach
的第一次迭代中运行。然后它会卡在那里,只会创建一个定时器。要解决此问题,需要将EV::run
移至foreach
之外。
然而,它根本不会做任何事情。那是因为事件循环无关。这是因为您在EV::timer
的正文中以词汇方式定义foreach
个对象。一旦完成一次迭代,该变量($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;