#!/usr/bin/perl -w ## Demonstration of event-driven interaction with a subprocess ## Event driven programming is a pain. This code is not that readable ## and is not a good place to start, especially since few people (including ## me) are familiar with bc's nuances. use strict; use IPC::Run qw( run ); die "usage: $0 <num>\n\nwhere <num> is a positive integer\n" unless @ARGV; my $i = shift; die "\$i must be > 0, not '$i'" unless $i =~ /^\d+$/ && $i > 0; ## bc instructions to initialize two variables and print one out my $stdin_queue = "a = i = $i ; i\n"; ## Note the FALSE on failure result (opposite of system()). die $! unless run( ['bc'], sub { ## Consume all input and return it. This is used instead of a plain ## scalar because run() would close bc's stdin the first time the ## scalar emptied. my $r = $stdin_queue; $stdin_queue = ''; return $r; }, sub { my $out = shift; print "bc said: ", $out; if ( $out =~ s/.*?(\d+)\n/$1/g ) { ## Grab the number from bc. Assume all numbers are delivered in ## single chunks and all numbers are significant. if ( $out > $i ) { ## i! is always >i for i > 0 print "result = ", $out, "\n"; $stdin_queue = undef; } elsif ( $out == '1' ) { ## End of calculation loop, get bc to output the result. $stdin_queue = "a\n"; } else { ## get bc to calculate the next iteration and print it out. $stdin_queue = "i = i - 1 ; a = a * i ; i\n"; } } }, );
Generated by dwww version 1.15 on Sun Jun 16 03:15:59 CEST 2024.