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.