当我去年问一个关于承诺的问题时,我的echo服务器正在工作(见这个链接:perl6如何获取承诺的特定身份?(。但是,随着 perl6 的新版本,我的 echo 服务器不再工作。
我想我可以尝试 perl6 文档站点 ( https://docs.perl6.org/type/IO::Socket::INET ( 中的示例,但我想找出我在代码中犯了什么错误。我目前的水平使我无法看到我的代码和 perl6 文档站点上的代码之间的差异。请给我一个提示;谢谢!
my @result;
for 0 .. 2 -> $index {
@result[$index] = start {
my $myPromiseID = $index;
say "======> $myPromiseIDn";
my $rsSocket = IO::Socket::INET.new:
localhost => 'localhost',
localport => 1234 + $index,
listen => 1;
while $rsSocket.accept -> $rsConnection {
say "Promise $myPromiseID accepted connection";
while $rsConnection.recv -> $stuff {
say "Promise $myPromiseID Echoing $stuff";
$rsConnection.print($stuff);
}
$rsConnection.close;
}
}
}
await @result;
错误消息是:
Tried to get the result of a broken Promise
in block <unit> at p6EchoMulti.pl line 24
Original exception:
Nothing given for new socket to connect or bind to
in block at p6EchoMulti.pl line 8
Actually thrown at:
in block at p6EchoMulti.pl line 13
这个提交在 Rakudo 更新日志的 2017 年 1 月部分宣布为"修复了 IPv6 URI 未正确解析的错误",只是修复了一个 URI 解析错误。它还完全重做了IO::Socket::INET.new
调用的参数绑定/验证,一个后果是它破坏了你的代码,因为更新的代码要求listen
是一个实际的Bool
,而不仅仅是强制一个。
旧代码(上面提交链接左侧的代码(有一个简单的method new (*%args is copy)
。这与您的通话相匹配。错误(fail "Nothing given for new socket to connect or bind to"
(没有触发,因为1
计算结果在布尔上下文中True
,所以%args<host> || %args<listen>
也被True
。因此,其余代码在设置为1
的情况下运行listen
并且一切正常。
来自 2017.01 的 Rakudos 在上面的提交链接右侧有代码。请注意现在有多个new
方法(即多个multi method new ...
声明(。
用于处理指定listen
参数的调用的 multi(s( 的形式为multi method new (..., Bool:D :$listen!, ...)
。请注意Bool:D
。
对new
的调用,listen
参数设置为True
,匹配此多数并按预期工作。
但是,带有:listen(1)
的呼叫只会匹配通用multi method new (*%args)
签名。后者做一个无条件的fail "Nothing given for new socket to connect or bind to";
。
好吧,经过一番挣扎,如果我将 listen=>1 更改为 listen=>True,它似乎有所改善。
谁能解释为什么 1 没有被评估为 True,以及为什么它以前有效?
谢谢。