run with $*OUT?

hello people,

<promotion shameless>
    French Perl Workshop is coming and would be a better
    event if *you* take part of it
    https://journeesperl.fr/jp2019/talks
</promotion>

now the problem ...

let's say i have a raku script to wrap mutt.
in this script, i have

* $body is the content of the body my message
* $subject and $recipient are self explainatory

from the shell, i call mutt those ways

    mutt -s $subject $recipient <<< $body
    mutt -s $subject $recipient <<.
    $body
    .

i'm searching for the shortest/simplest way to
do that in raku (meaning stay away from react/whenever for very basic
usages) .

so it seemed to me that `run` is a good candidate
and expect filehandlers or filenames to setup the std.

i tried some variations around

    my $p = run 'cat', '-n', in => $*OUT, :out;
    $*OUT.say for < i bet on you, raku >;
    $*ERR.say: $p.out.slurp;

    my $p = run 'cat', '-n', in => "/dev/stdout", :out;
    $*OUT.say for < i bet on you, raku >;
    $*ERR.say: $p.out.slurp;

    my $o2 = $*OUT.clone;
    my $p = run 'cat', '-n', in => $o2, :out;
    $o2.say for < i bet on you, raku >;
    $*ERR.say: $p.out.slurp;

    ...

none of those made raku unhappy but none of them does the job.
i'm on my way to use Proc::Async.new ... but before that, i would like
to ask if there is a simpler solution.

regards,
marc
0
eiro
6/6/2019 3:01:13 PM
perl.perl6.users 1218 articles. 0 followers. Follow

4 Replies
69 Views

Similar Articles

[PageSpeed] 59

On Thursday, June  6, Marc Chantreux wrote: 
>     my $p = run 'cat', '-n', in => $*OUT, :out;
>     $*OUT.say for < i bet on you, raku >;
>     $*ERR.say: $p.out.slurp;
> 
>     my $p = run 'cat', '-n', in => "/dev/stdout", :out;
>     $*OUT.say for < i bet on you, raku >;
>     $*ERR.say: $p.out.slurp;
> 
>     my $o2 = $*OUT.clone;
>     my $p = run 'cat', '-n', in => $o2, :out;
>     $o2.say for < i bet on you, raku >;
>     $*ERR.say: $p.out.slurp;

Something like this?

	my $p = run 'cat', '-n', :in, :out;
	$p.in.say($_) for <i bet on you raku>;
	$p.in.close;
	say $p.out.slurp;

which produces

     1  i
     2  bet
     3  on
     4  you
     5  raku
0
bduggan
6/6/2019 3:51:38 PM
--yrj/dFKFPuw6o+aM
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

> Something like this?

> 	my $p = run 'cat', '-n', :in, :out;
> 	$p.in.say($_) for <i bet on you raku>;
> 	$p.in.close;
> 	say $p.out.slurp;

*that* simple!!! perfect ... thanks a lot!

this isn't obvious to guess that '-' means "you can connect the
subprocess directly to the perl interpreter". i really think this
example is worth to be added in the documentation.

also, i guess that the way the example is written will cause some
infinite iowait when we write a big enough amount of data to fill the
buffer (i don't know if it's correct).

so maybe this exemple should be added too?

    my $p = run 'cat', '-n', :in, :out;
    for <i bet on you raku> {
        $p.in.say($_);
        say $p.out.lines(1)[0];
    }
    $p.in.close;

how about the attached patch?

regards
marc






--yrj/dFKFPuw6o+aM
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="run-in.diff"

diff --git a/doc/Type/independent-routines.pod6 b/doc/Type/independent-routines.pod6
index 6142ebd3..f456b970 100644
--- a/doc/Type/independent-routines.pod6
+++ b/doc/Type/independent-routines.pod6
@@ -536,6 +536,30 @@ creating a kind of I<pipe>:
     my $proc = run "ls", "-alt", :out($ls-alt-handle);
     # (The file will contain the output of the ls -alt command)
 
+The standard input can be redirected as well so a bidirectional communication
+can be establish with the run process.
+
+    my $p = run 'cat', '-n', :in, :out;
+    for <i bet on you raku> { $p.in.say($_) }
+    $p.in.close;
+    say $p.out.slurp;
+    # 1	i
+    # 2	bet
+    # 3	on
+    # 4	you
+    # 5	raku
+
+the last example isn't a good idea if you deal with a great amount of data so
+you can also interact with the process line by line.
+
+    my $p = run 'cat', '-n', :in, :out;
+    for <i bet on you raku> {
+        $p.in.say($_);
+        say $p.out.lines(1)[0];
+    }
+    $p.in.close;
+
+
 These argument are quite flexible and admit, for instance, handles to
 redirect them. See L<Proc|/type/Proc> and
 L<Proc::Async|/type/Proc::Async> for more details.

--yrj/dFKFPuw6o+aM--
0
eiro
6/6/2019 6:02:14 PM
On Thursday, June  6, Marc Chantreux wrote: 
> this isn't obvious to guess that '-' means "you can connect the
> subprocess directly to the perl interpreter". i really think this
> example is worth to be added in the documentation.

Actually -- looks like it is there :-) though on the
Proc page, not the 'run' page --

  https://docs.perl6.org/type/Proc

> +    my $p = run 'cat', '-n', :in, :out;
> +    for <i bet on you raku> {
> +        $p.in.say($_);
> +        say $p.out.lines(1)[0];
> +    }
> +    $p.in.close;

I'm curious about whether you could rely
on a line being emitted right away -- e.g.
if there is some output-buffering of the
command -- this might be better handled by
a react/whenever construct.

Brian
0
bduggan
6/6/2019 6:32:38 PM
hello,

> Actually -- looks like it is there :-) though on the
> Proc page, not the 'run' page --

too far from the expected lines. so maybe we should just add a link ?

> I'm curious about whether you could rely
> on a line being emitted right away -- e.g.
> if there is some output-buffering of the
> command

well ... they told me that they torment implementers instead of users
so i guess i can trust this code :)

thanks,
marc
0
eiro
6/6/2019 7:21:59 PM
Reply: