gpt4 book ai didi

perl - 在使用 ("1"时,无法使用字符串 "strict refs") 作为子例程引用

转载 作者:行者123 更新时间:2023-12-02 10:36:21 25 4
gpt4 key购买 nike

在对各种事件使用react的 Perl 守护进程中,我尝试使用 a Null object pattern在 2 种情况下,通过创建匿名子例程,该子例程应该只返回值 1 又名“true”(请滚动到右侧以查看 LOGINcheck 子例程>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;

不幸的是,我收到 LOGIN 事件的运行时错误:

Can't use string ("1") as a subroutine ref while "strict refs" in use

有人知道如何解决这个问题吗?

如何向匿名 Perl 子例程提供“函数指针”?

处理程序 =>\&sub { 1 } 也不执行此操作。

在 CentOS 5.x 和 6.x 上使用 perl 5.8.8 和 perl 5.10.1

更新:

我还尝试过以下操作:

    my $check = $EVENTS{$event}->{check};
return unless $check->($user, $arg);

但这没有帮助。我认为这排除了一些答案中建议的“缺失的祝福”。

更新2:

我在原来的问题中扩展了源代码片段。 背景是:我正在重构我的源代码,因此我创建了上面列出的 %EVENTS 哈希,以便对于每个传入的< em>event(通过 TCP 套接字从 a Flash client 发送的字符串)存在对验证事件的子例程 (check) 的引用以及对另一个子例程的引用 (check) >handler) 执行一些操作。我不确定其他子例程是否有效 - 我已经陷入第一个登录事件

我也不明白为什么上面的 check => sub { 1 } 不起作用 - 不应该 sub 返回对匿名子例程的引用(当省略名称时 - 根据 perldoc perlref 第 4 节)?

更新3:

print Dumper(\%EVENTS) 的输出 -

$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" },
}
};

最佳答案

问题不在于出现问题的特定事件;而是在于。实际的错误是在 action 中。特别是,该行

    return unless $user->$check->($arg); # XXX fails

并没有像你想象的那样做。在原型(prototype)的存在和 Perl 愿意尝试调用按名称指定的子程序之间,您最终会为 CHAT 事件调用 User:: 。这似乎不是您想要的。

更正确的调用看起来像

    return unless $check->($user, $arg);

这期望 $check 包含一个子引用(它确实如此),取消引用它并调用它。即使有时 $check 会引用原型(prototype)函数,这种方法仍然有效。

这就留下了这个过程代码不尊重继承的问题。为此,您必须稍微改一下 %EVENTS 的措辞。因此:

our %EVENTS = (
LOGIN => {handler => \&handleLogin, check => sub {1}, },
CHAT => {handler => \&handleChat, check => sub { shift->mayChat(@_) },
...
);

请注意,强烈建议您混合使用函数原型(prototype)和 Perl OO 编程,因为这可能会导致像这样的难以诊断的问题。

引用您的其他问题:my $foo = sub { } 确实是构造匿名子例程的方式。但您确实需要适本地调用它们。

关于perl - 在使用 ("1"时,无法使用字符串 "strict refs") 作为子例程引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9929754/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com