perl6 与去年相比 IO::Socket::INET 的变化和失信
perl6 Changes in IO::Socket::INET from last year and broken promises
当我去年问一个关于 promises 的问题时,我的 echo 服务器正在工作(参见 link: )。但是,使用新版本的 perl6,我的回显服务器不再工作。
我想我可以尝试 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
好吧,折腾了一番,把listen=>1改成listen=>True好像有改善。
谁能解释一下为什么 1 没有被评估为 True,为什么它以前有效?
谢谢。
This commit, which was announced in the Jan 2017 section of Rakudo's changelog 因为 "Fixed bug where IPv6 URIs were not parsed correctly" 做了很多,只是修复了一个 URI 解析错误。它还完全重写了 IO::Socket::INET.new
调用的参数 binding/validation,结果是它破坏了您的代码,因为更新后的代码要求 listen
是实际的 Bool
,而不仅仅是强制为一个。
旧代码(上面提交 link 左侧的代码)有一个简单的 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 在上面的提交 link 右侧有代码。请注意现在有多个 new
方法(即多个 multi method new ...
声明)。
multi(s) 旨在处理指定 listen
参数 is/are 形式 multi method new (..., Bool:D :$listen!, ...)
的调用。注意 Bool:D
.
调用 new
,将 listen
参数设置为 True
,匹配此 multi 并按预期工作。
但是使用 :listen(1)
的调用将只匹配通用的 multi method new (*%args)
签名。后者执行无条件 fail "Nothing given for new socket to connect or bind to";
.
当我去年问一个关于 promises 的问题时,我的 echo 服务器正在工作(参见 link:
我想我可以尝试 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
好吧,折腾了一番,把listen=>1改成listen=>True好像有改善。
谁能解释一下为什么 1 没有被评估为 True,为什么它以前有效?
谢谢。
This commit, which was announced in the Jan 2017 section of Rakudo's changelog 因为 "Fixed bug where IPv6 URIs were not parsed correctly" 做了很多,只是修复了一个 URI 解析错误。它还完全重写了 IO::Socket::INET.new
调用的参数 binding/validation,结果是它破坏了您的代码,因为更新后的代码要求 listen
是实际的 Bool
,而不仅仅是强制为一个。
旧代码(上面提交 link 左侧的代码)有一个简单的 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 在上面的提交 link 右侧有代码。请注意现在有多个 new
方法(即多个 multi method new ...
声明)。
multi(s) 旨在处理指定 listen
参数 is/are 形式 multi method new (..., Bool:D :$listen!, ...)
的调用。注意 Bool:D
.
调用 new
,将 listen
参数设置为 True
,匹配此 multi 并按预期工作。
但是使用 :listen(1)
的调用将只匹配通用的 multi method new (*%args)
签名。后者执行无条件 fail "Nothing given for new socket to connect or bind to";
.