The Idiot's Guide To Reading The Keyboard

David Cantrell david at cantrell.org.uk
Tue Feb 26 17:12:02 GMT 2008


I need to be able to make a particular method call asynchronously, and
to call it very frequently - about a hundred times a second should be
about right - and if possible read a character from STDIN and pass it to
the method, without blocking.

The obvious solution is a select() loop, but I just can't wrap my head
around four-arg select.  Tried it several times, read the man pages
backwards and forwards, looked in the cookbook, can't do it.
The next most obvious solution is POE.  But unfortunately its
documentation still favours completeness over usefullness.  There's lots
of stuff in there about reading lines of text from STDIN, or reading
from a notwork socket, but try as I might I can't combine them to read a
character if one is available.

So I did this ...

use Time::HiRes qw(setitimer ITIMER_REAL);
use Term::ReadKey;

... [stuff here to create an object $o] ...

setitimer(ITIMER_REAL, 1, 0.01); # after 1 sec, ALRM every 0.01 sec
$SIG{ALRM} = sub {
    ReadMode 'cbreak';
    ReadMode 'noecho';
    $o->deal_with_input(ReadKey(-1));
    ReadMode 'normal';
};

$o->loop_forever();

Banging my head against select() and POE took a good couple of hours
last night, with nothing to show for it.  Reading perlfaq8 at lunchtime
took about five minutes.

On IRC, Nicholas said that this was sick.  I'm not sure why he thinks
that, but I'll take it as a compliment :-)

-- 
David Cantrell | top google result for "internet beard fetish club"

"IMO, the primary historical significance of Unix is that it marks the
time in computer history where CPUs became so cheap that it was possible
to build an operating system without adult supervision."
                         -- Russ Holsclaw in a.f.c


More information about the london.pm mailing list