in reply to Re^18: CPAN and readline on windows
in thread CPAN and readline on windows

I'm pretty much convinced that it is Term::ReadLine, or at least Term::ReadKey, specifically, ReadKey.xs

Which version of Term::ReadKey do you have ? (I have 2.30.)

Cheers,
Rob

Replies are listed 'Best First'.
Re^20: CPAN and readline on windows
by BrowserUk (Patriarch) on Mar 28, 2009 at 07:46 UTC

    I also have Term::ReadKey v2.30. But here's what I suspect is happening. If I run perldl under Devel::Trace, when it finally stops for input, it does so here:

    >> [0] C:/Perl64/lib/Term/ReadKey.pm : 274: if ( ref($file) ) { r +eturn $file; } # Reference is fine >> [0] (eval 9)[C:/Perl64/lib/Term/ReadKey.pm:522]: 3: ??? >> [0] (eval 9)[C:/Perl64/lib/Term/ReadKey.pm:522]: 7: ??? >> [0] (eval 9)[C:/Perl64/lib/Term/ReadKey.pm:522]: 8: ???

    Now that relates to this runtime generated subroutine:

    sub ReadKey { my($File) = normalizehandle((@_>1?$_[1]:\*STDIN)); if ($_[0]) { Win32PeekChar($File, $_[0]); } else { getc $File; } #if ($_[0]!=0) {return undef if !Win32PeekChar($File, $_[0])}; #getc $File; }

    On my system, it goes to the else branch of the if statement, and getc. As far as I am aware, there is no possibility for getc to ever return keystrokes/virtual keycodes that are generated by the extended keys--which is the exact symptoms I am seeing.

    However, if I hardcode the if condition to force it to go through the Win32PeekChar() branch, then pressing the extended keys does have an affect!. They don't work, but they are seen.

    My (pretty confident) guess is that if you traced perldl, you'd find that pressing the extended keys does have an effect, and if you added a little trace, you'd find that on your system, the code is passing through the upper branch of the if statement. The question then becomes why does it do so for you, and not for ikegami and me.

    And that's where life gets messy, because the controlling factor of which branch the code takes is down to the arguments passed in from Term::ReadLine()--which is a crufty old module that stems from Perl4 and still has all the leftovers; no strict vars; global variables; the works.

    Specifically, the upper branch and Win32PeekChar() will only be called if the first argument to ReadKey() is true. But on my system, the call to ReadKey() comes from line 2082 of Term::ReadLine.pm:

    sub rl_getc { my $key; # JP: Added missing declaration if (defined $term_readkey) { # XXXX ??? $Term::ReadLine::Perl::term->Tk_loop if $Term::ReadLine::toloop && defined &Tk::DoOneEvent; $key = Term::ReadKey::ReadKey(0, $term_IN); ### 2082 } else { $key = $Term::ReadLine::Perl::term->get_c; } }

    But there, the first argument is hardcoded to be false (0), so (assuming your system is taking another path), it must be arriving in ReadKey() via a different route. Your first reaction is likely to be to look at $term_readkey (mine was), but I think that is a read herring. It simply records whether Term::ReadKey was successfully loaded.

    rl_gets() is only called in one place:

    sub getc_with_pending { my $key = @Pending ? shift(@Pending) : &$rl_getc; # Save keystrokes for vi '.' command push(@$Dot_buf, $key) if $Dot_buf; $key; }

    Unfortunately, that gets called all over the place, so that stops my investigation in it's tracks. At least until (if) you trace yours through to see what's different.

    My best guess at this point. Are you a vi or emacs user? Do you have some environment variable (say:'editor' or similar) that might influence the behaviour of Term::*?


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      I also have Term::ReadKey v2.30

      I can find no evidence that Term::ReadKey comes into play for me - and perhaps that's the secret to my success. If I stick a print in both the 'if' and 'else' branches of that sub ReadKey (and I made sure I selected the same rendition of that sub), then I don't get to see *either* of them when firing up the cpan and perldl shells. And I know that nothing changes if I remove Term::ReadKey - both the perldl and cpan shells still work exactly as before.

      Are you a vi or emacs user?

      Notepad ... real sophisticated :-)

      Cheers,
      Rob
Re^20: CPAN and readline on windows
by ikegami (Patriarch) on Mar 28, 2009 at 03:59 UTC
    Same.

    Did you try

    perl -MTerm::ReadLine -e"$t=Term::ReadLine->new('test'); 1 while (defi +ned($t->readline(': ')))"
      I hadn't tried that:
      C:\>perl -MTerm::ReadLine -e"$t=Term::ReadLine->new('test'); 1 while ( +defined($t->readline(': ')))" : ab : ab :
      The first 'ab' was entered by typing the characters in. The second 'ab' was entered by hitting the up arrow.

      Cheers,
      Rob