perl6来自去年的IO :: Socket :: INET的变化和破坏的承诺

时间:2017-08-21 02:19:19

标签: sockets server promise perl6

当我去年问一个关于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

2 个答案:

答案 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,为什么它之前有效?

感谢。