Unrecursing
Moritz was unhappy with the power Raku gave him to wrestle with lists. And he is right. If easy things are easy, no wrestling is required. That made me think about the data structure I build in my last blog post. It’s a list of pairs of a list and a Proc::Async
.
[[[Proc::Async],Proc::Async],Proc::Async]
Whereby the list has the method .start
mixed in. That allows me to connect the shell commands in order and start them in reverse order without special casing to get .start
called. After all I need to connect STDOUT and STDIN before I start a pair of shell commands. However, any form of introspection becomes a burden. And I need to check if an Array is not at the start or end of a pipe chain.
@a |> $grep |> $sort; # this is fine
$find |> $sort |> @a; # this too
$find |> @a |> $sort; this can not work
An Array is not a concurrent data structure. The left and right side of the chain are. So we can’t mix them. (I believe I can make this work when R#3778 is fixed.)
So I rewrote what I had so far. As a side effect we can store a pipe and start it later by hand and provide a nice gist.
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
Whereby $p
contains a Shell::Pipe
which has @.pipees
. So we can do something like this.
for $p.pipees -> $p { $p.stderr.tap(-> {}) if $p ~~ Proc::Async}; # silence is golden
$p.start;
I want to support Supplies, Channels and Callables as start and end of a pipe. Maybe even in between. Then I can move on to tackle error handling.
It is very tempting to build elaborate data structures because Raku is so good at deconstructing them. This seams to be an option best to be avoided. Elegance might just be the solution with the least moving parts.
-
July 6, 2020 at 16:532020.27 Advanced Beginning – Rakudo Weekly News