当我去年问一个关于promises的问题时,我的echo服务器正在工作(请参阅此链接:perl6 how to get specific identity of promises?)。但是,对于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 "======> $myPromiseID\n";
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
答案 0 :(得分:2)
This commit,其中announced in the Jan 2017 section of Rakudo's changelog为“修正了未正确解析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
。所以代码的其余部分在listen
设置为1
的情况下运行,这一切都很顺利。
2017.01的Rakudos在上面的提交链接右边有代码。请注意现在有多种new
方法(即多个multi method new ...
声明)。
旨在处理指定listen
参数的调用的多个是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";
。
答案 1 :(得分:1)
好吧,经过一番挣扎,如果我改变了listen =&gt; 1来监听=&gt; True,它似乎有所改善。
任何人都可以解释为什么1没有被评估为True,为什么它之前有效?
感谢。