В демоне Perl, реагирующем на различные события, я пытаюсь использовать шаблон пустого объекта в 2 случаях, создавая анонимные подпрограммы, которые должны просто возвращать значение 1 или «true» (пожалуйста, прокрутитевправо, чтобы увидеть подпрограммы check для событий LOGIN и ALIVE ):
package User;
our %EVENTS = (
LOGIN => {handler => \&handleLogin, check => sub {1}, },
CHAT => {handler => \&handleChat, check => \&mayChat, },
JOIN => {handler => \&handleJoin, check => \&mayJoin, },
LEAVE => {handler => \&handleLeave, check => \&mayLeave, },
ALIVE => {handler => sub {}, check => sub {1}, },
BID => {handler => \&handleBid, check => \&checkArgs, },
TAKE => {handler => \&handleTake, check => \&checkArgs, },
# .... more events ....
);
sub action($$$) {
my $user = shift;
my $event = shift;
my $arg = shift;
my $game = $user->{GAME};
unless (exists $EVENTS{$event}) {
print STDERR "wrong event: $event\n";
return;
}
my $handler = $EVENTS{$event}->{handler};
my $check = $EVENTS{$event}->{check};
return unless $user->$check->($arg); # XXX fails
$user->$handler->($arg);
}
sub mayChat($$) {
my $user = shift;
return if $user->{KIBITZER};
}
# ...... more methods here ...
1;
К сожалению, я получаю ошибку времени выполнения для ВХОД событие:
Can't use string ("1") as a subroutine ref while "strict refs" in use
Кто-нибудь знает, пожалуйста, как это исправить здесь?
Как предоставить «указатель функции» на анонимную подпрограмму Perl?
Обработчик => \ & sub {1} тоже не делает этого.
Использование perl 5.8.8 и perl 5.10.1 в CentOS 5.x и6.x
ОБНОВЛЕНИЕ:
Я также попробовал следующее:
my $check = $EVENTS{$event}->{check};
return unless $check->($user, $arg);
, но это не помогает.Я думаю, что это исключает «недостающее благословение», предложенное в некоторых ответах.
ОБНОВЛЕНИЕ 2:
Я расширил фрагмент исходного кода в моем исходном вопросе. Фон: Я в процессе рефакторинга моего исходного кода и, таким образом, я создал хэш % EVENTS , как указано выше, так что для каждого входящего В событии (строка, отправляемая через TCP-сокет из клиента Flash ), имеется ссылка на подпрограмму ( check ), которая проверяет событие, и ссылку на другую подпрограмму ( обработчик ), который выполняет некоторые действия.Я не уверен, работают ли другие подпрограммы - я застрял уже на первом LOGIN событие .
Я также не понимаю, почему не check => sub {1} выше работы - не sub должен возвращать ссылку на анонимную подпрограмму (если имя опущено - согласно perldoc perlref раздел 4)?
ОБНОВЛЕНИЕ 3:
Выход Печать Dumper (\% СОБЫТИЯ) -
$VAR1 = {
'PLAY' => {
'check' => sub { "DUMMY" },
'handler' => sub { "DUMMY" },
},
'JOIN' => {
'check' => sub { "DUMMY" },
'handler' => sub { "DUMMY" },
},
'OVER1' => {
'check' => sub { "DUMMY" },
'handler' => sub { "DUMMY" },
},
'ALIVE' => {
'check' => sub { "DUMMY" },
'handler' => sub { "DUMMY" },
},
'DISCARD' => {
'check' => $VAR1->{'PLAY'}{'check'},
'handler' => sub { "DUMMY" },
},
'MISS1' => {
'check' => sub { "DUMMY" },
'handler' => sub { "DUMMY" },
},
'LOGIN' => {
'check' => sub { "DUMMY" },
'handler' => sub { "DUMMY" },
},
'TAKE' => {
'check' => $VAR1->{'PLAY'}{'check'},
'handler' => sub { "DUMMY" },
},
'ONEMORE' => {
'check' => sub { "DUMMY" },
'handler' => sub { "DUMMY" },
},
'OVER2' => {
'check' => sub { "DUMMY" },
'handler' => sub { "DUMMY" },
},
'MISS2' => {
'check' => sub { "DUMMY" },
'handler' => sub { "DUMMY" },
},
'EXACT' => {
'check' => sub { "DUMMY" },
'handler' => sub { "DUMMY" },
},
'TRUST' => {
'check' => $VAR1->{'PLAY'}{'check'},
'handler' => sub { "DUMMY" },
},
'LEAVE' => {
'check' => sub { "DUMMY" },
'handler' => sub { "DUMMY" },
},
'DEFEND' => {
'check' => $VAR1->{'PLAY'}{'check'},
'handler' => sub { "DUMMY" },
},
'OPEN' => {
'check' => $VAR1->{'PLAY'}{'check'},
'handler' => sub { "DUMMY" },
},
'REVEAL' => {
'check' => sub { "DUMMY" },
'handler' => sub { "DUMMY" },
},
'CHAT' => {
'check' => sub { "DUMMY" },
'handler' => sub { "DUMMY" },
},
'DECLARE' => {
'check' => $VAR1->{'PLAY'}{'check'},
'handler' => sub { "DUMMY" },
},
'BACK' => {
'check' => sub { "DUMMY" },
'handler' => sub { "DUMMY" },
},
'MISERE' => {
'check' => sub { "DUMMY" },
'handler' => sub { "DUMMY" },
},
'BID' => {
'check' => $VAR1->{'PLAY'}{'check'},
'handler' => sub { "DUMMY" },
}
};