読者です 読者をやめる 読者になる 読者になる

perl6で外部プログラムの出力を操作する

perl6でperl5のあれどうやるの1回目。

perlをshell++なものとして使うことはよくある。例えば、外部プログラムを実行しそのstdoutに時刻をつけていくには

use strict;
use warnings;
use POSIX qw(strftime);

my @cmd = ('perl', '-E', '$|++; for (1..10) { say $_; sleep 1 }');
open my $fh, "-|", @cmd or die;
while (<$fh>) {
    printf "[%s] %s", strftime("%F %T", localtime), $_;
}
close $fh;

みたいにすると思う。

> perl test.pl
[2015-09-05 16:25:03] 1
[2015-09-05 16:25:04] 2
[2015-09-05 16:25:05] 3
...

これをperl6でやろうとするとこんな感じか。

use v6;

my @cmd = 'perl', '-E', '$|++; for (1..10) { say $_; sleep 1 }';
my $proc = Proc::Async.new(|@cmd);
$proc.stdout.tap(-> $str {
    printf "[%s] %s", DateTime.now, $str;
});
my $promise = $proc.start;
await $promise;

さらにperl6では何も考えずに外部プログラムを増やせる。いい!

use v6;

my @promise = do for 1..2 {
    my @cmd = 'perl', '-E', '$|++; for (1..10) { say $_; sleep 1 }';
    my $proc = Proc::Async.new(|@cmd);
    $proc.stdout.tap(-> $str {
        printf "[%s] %s", DateTime.now, $str;
    });
    $proc.start;
}
await |@promise;

(ときどき意味不明なエラー出るけど)