Wait the light to fall

非递归

焉知非鱼

categories: [“Raku”] #

Moritz 不满意 Raku 给他的权力,让他与名单搏斗。他说的没错。如果简单的事情很容易,就不需要摔跤了。这让我想到了我在上一篇博文中构建的数据结构。它是一个列表和一个 Proc::Async 的对。

[[[Proc::Async],Proc::Async],Proc::Async]

其中,列表中混入了 .start 方法。这样我就可以按顺序连接 shell 命令,并按相反的顺序启动它们,而不需要特殊的套管来让 .start 被调用。毕竟在启动一对shell命令之前,我需要连接 STDOUT 和 STDIN。然而,任何形式的反省都会成为一种负担。而且我需要检查一个 Array 是否不在一个管道链的开始或结束。

@a |> $grep |> $sort; # this is fine
$find |> $sort |> @a; # this too
$find |> @a |> $sort; this can not work

数组不是一个并发的数据结构。链的左边和右边是。所以我们不能把它们混在一起。(我相信当 R#3778 修复后,我可以让这个工作。)

所以我重写了目前的内容。作为一个副作用,我们可以存储一个管道,并在以后手动启动它,并提供一个很好的要领。

my $find = Proc::Async.new('/usr/bin/find', '/tmp');
my $sort = Proc::Async.new('/usr/bin/sort');
my @a;
my $p = $find |> $sort |> @a;
say $p;
#OUTPUT: find ↦ sort ↦ @a

其中 $p 包含一个 Shell::Pipe,它有 @.pipees。所以我们可以这样做。

for $p.pipees -> $p { $p.stderr.tap(-> {}) if $p ~~ Proc::Async}; # silence is golden
$p.start;

我希望支持 Supply、Channel 和 Callable 作为一个管道的开始和结束。也许甚至在两者之间。然后我就可以继续处理错误处理。

构建复杂的数据结构是非常有诱惑力的,因为 Raku 是如此善于分解它们。这似乎是一个最好避免的选择。优雅可能只是一个解决方案,它的移动部件最少。

by gfldex.