perl6 IO::Socket::INET 与去年相比的变化和违背承诺



当我去年问一个关于承诺的问题时,我的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,以及为什么它以前有效?

谢谢。

最新更新