I'm trying to see if I can get Term::ReadLine to work in an event loop other than Tk, but the authors have made it somewhat difficult. And I've been having a bit of trouble trying to override things appropriately.

The first step was simply to test that something was happening in the background while waiting, just with the Tk loop. I found it easiest just to put a timer in with some ANSI control codes to move the cursor around - not the best way of doing this, but it works.

#!/usr/bin/perl use 5.12.1; my $esc; BEGIN { $esc = "\x1b["; print "${esc}2J${esc}3H"; } use Tk; use AnyEvent; use Term::ReadLine; my $t = 0; my $w = AE::timer (0,1,sub {print "${esc}s${esc}1H$t s ${esc}u";+ ++$t}); my $term = Term::ReadLine->new('...'); $term->tkRunning(1); my $x = $term->readline('> ');
This works. I get a prompt, I can type in it, and the timer triggers counting the seconds at the top of the console. Unfortunately, it's using Tk. I'm using AnyEvent for the timer at least, because I really don't want to be looking at all the event loops to figure out how to get that to work.

My next attempt was to try to get the loop itself done in AnyEvent. Here things start to go downhill. Note that I'm still using Tk, just in case.

#!/usr/bin/perl use Tk; use AnyEvent; use Term::ReadLine; use IO::File; use 5.12.1; sub LOG { state $fh; open $fh, '>', '/tmp/sopw.out' unless $fh; die $! unless $fh; autoflush $fh 1; say $fh @_; } package Term::ReadLine::AE; # mangle their tree, inserting ourselves in the front. unshift @Term::ReadLine::Stub::ISA, __PACKAGE__; #use Data::Dump qw(ddx); #ddx(\%INC); if (not defined &Tk::DoOneEvent) { ::LOG("overriding"); *Tk::DoOneEvent = sub { AnyEvent->_poll(); }; ::LOG("Not created?") unless defined &Tk::DoOneEvent; } our $cv; sub Tk_loop { my $self = shift; ::LOG("Entering Tk_loop");# unless $cv; $cv = AE::cv; $cv->recv(); } sub register_Tk { my $self = shift; ::LOG("Registering"); $Term::ReadLine::registered++ or AE::io($self->IN, 0, sub { $cv->send() }); } package main; use 5.12.1; my $esc; BEGIN { $esc = "\x1b["; print "${esc}2J${esc}3H"; } my $t = 0; my $w = AE::timer (0,1,sub {print "${esc}s${esc}1H$t s ${esc}u";+ ++$t}); my $term = Term::ReadLine->new('...'); $term->tkRunning(1); my $x = $term->readline('> ');
The basic code is the same, I've merely inserted a new package to override the Tk_loop and register_Tk functions - register seems to register the filehandle for monitoring while the loop, well, loops until characters are ready on the input. However, it "doesn't work." Specifically, the timer still fires, but the input isn't recognised. The io watcher never fires. (The override on Tk::DoOneEvent also isn't used - that was there for what I was hoping to be the next step - switching Tk to EV.)

It looks like AnyEvent's Tk implementation duplicates filehandles all over the place for monitoring, the author claims it's to workaround some Tk bugs. I don't know, but even if I switch out EV for Tk, I get the same behaviour: my typing isn't recognised but the timer fires fine. I'm kind of at a loss to explain what's going on here and hoping someone else has the required tuits.

Thanks!

Update: Nevermind. Found the solution. I forgot that AE events have watcher objects. I need to keep the return from AE::io, otherwise the object goes out of scope and is deleted. I'll have to store the watcher:

our $fe; sub register_Tk { my $self = shift; ::LOG("Registering"); $fe ||= AE::io($self->IN, 0, sub { $cv->send() }); }
And suddenly they all work. Now to figure out how to make this suggestion to the owners of TRL :-)


In reply to Using Term::ReadLine in an event loop other than Tk [SOLVED] by Tanktalus

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.