A
Andrei Alexandrescu (See Website For Email)
Hello everybody,
I've written a small utility that allows Perl to communicate with TeX
(knowledge of TeX is not necessary to understand my question). Basically
I run perl to communicate with two pipes: perlin.tex and perlout.tex.
Perl reads a line off perlin.tex, evaluates the string, and writes it to
perlout.tex. Here's what I came up with:
===========================================
#!/bin/env perl
use strict;
use warnings;
system("rm -f perlin.tex perlout.tex && mkfifo perlin.tex perlout.tex") == 0
or die "Couldn't create pipes";
while () {
print "Opening perlin.tex...\n";
open(my $perlin, "perlin.tex") or die "Can't open: $!";
print "Opened perlin.tex\n";
print "Opening perlout.tex...\n";
open(my $perlout, ">perlout.tex") or die "Can't open: $!";
print "Opened perlout.tex\n";
$| = 1;
while (<$perlin>) {
chomp;
print "Read a line: `$_'\n";
next if $_ eq "";
my $r = eval($_);
die $@ if $@;
chomp $r;
print $perlout "$r\n";
}
print "Input pipe finished.\n";
}
===========================================
Test code:
$ perl perlengine.pl &
$ echo "1+1" > perlin.tex
$ cat perlout.tex
2
$ _
(Ignoring, of course, all of the debug messages.)
The question is, how can I make the code more efficient? I noticed that
every evaluation is really a pass through the outer loop. In other
words, I was unable to convince perl to block in <$perlin> once the
process writing to perlin.tex has finished. I need to reopen perlin.tex
for that; the call to open will block until someone wrote to perlin.tex.
Is there any chance of avoiding the expensive trip of opening and
closing the whole thing over and over again? Can I tell perl, "read to
the EOF of this pipe, and then rewind and read again, blocking if nobody
wrote to it"?
Thanks,
Andrei
I've written a small utility that allows Perl to communicate with TeX
(knowledge of TeX is not necessary to understand my question). Basically
I run perl to communicate with two pipes: perlin.tex and perlout.tex.
Perl reads a line off perlin.tex, evaluates the string, and writes it to
perlout.tex. Here's what I came up with:
===========================================
#!/bin/env perl
use strict;
use warnings;
system("rm -f perlin.tex perlout.tex && mkfifo perlin.tex perlout.tex") == 0
or die "Couldn't create pipes";
while () {
print "Opening perlin.tex...\n";
open(my $perlin, "perlin.tex") or die "Can't open: $!";
print "Opened perlin.tex\n";
print "Opening perlout.tex...\n";
open(my $perlout, ">perlout.tex") or die "Can't open: $!";
print "Opened perlout.tex\n";
$| = 1;
while (<$perlin>) {
chomp;
print "Read a line: `$_'\n";
next if $_ eq "";
my $r = eval($_);
die $@ if $@;
chomp $r;
print $perlout "$r\n";
}
print "Input pipe finished.\n";
}
===========================================
Test code:
$ perl perlengine.pl &
$ echo "1+1" > perlin.tex
$ cat perlout.tex
2
$ _
(Ignoring, of course, all of the debug messages.)
The question is, how can I make the code more efficient? I noticed that
every evaluation is really a pass through the outer loop. In other
words, I was unable to convince perl to block in <$perlin> once the
process writing to perlin.tex has finished. I need to reopen perlin.tex
for that; the call to open will block until someone wrote to perlin.tex.
Is there any chance of avoiding the expensive trip of opening and
closing the whole thing over and over again? Can I tell perl, "read to
the EOF of this pipe, and then rewind and read again, blocking if nobody
wrote to it"?
Thanks,
Andrei