the problem
I recently heard monks complaining that applications using Term::ReadLine can't be debugged within the perldebugger b/c it's interface relies on Term::Readline.
the trick
here one solution (at least for linux) I wanted to have documented (before I forget it again ;)call the script you want to debug (here calc_TRL.pl ) from a shell with
PERLDB_OPTS="TTY=`tty` ReadLine=0" xterm -e perl -d ./calc_TRL.pl
and a second xterm will be opened running the program.
how it works
a second xterm is started running the debugger, but b/c of the TTY setting in PERLDB_OPTS all debugger communication goes via the parent xterm , while the calc app normally displays in the child xterm .
ReadLine=0 tells the debugger not to rely on a working Term::ReadLine.
NB: It's important that calling the second xterm blocks the execution in the first xterm till it's finished. Like this keystrokes aren interpreted by two applications in the first xterm. Just put an & at the end to see how things get messed up otherwise if the shell tries to step in.
how it looks like
first xterm
becomes the front end for the debugger
> PERLDB_OPTS="TTY=`tty` ReadLine=0" xterm -e perl -d ./calc_TRL.pl Loading DB routines from perl5db.pl version 1.33 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(./calc_TRL.pl:2): my $term = Term::ReadLine->new('Simple Per +l calc'); DB<1> l 2==> my $term = Term::ReadLine->new('Simple Perl calc'); 3: my $prompt = "Enter code: "; 4: my $OUT = $term->OUT || \*STDOUT; 5: while ( $_ = $term->readline($prompt) ) { 6: my $res = eval($_); 7: warn $@ if $@; 8: print $OUT $res, "\n" unless $@; 9: $term->addhistory($_) if /\S/; 10 } 11 DB<1> b 9 DB<2> c main::(./calc_TRL.pl:9): $term->addhistory($_) if /\S/; DB<2> c main::(./calc_TRL.pl:9): $term->addhistory($_) if /\S/; DB<3>
as you see I get the lines from the app in the second xterm listed can set a breakpoint at the end of the loop and tell twice to continue till next breakpoint.
second xterm
runs the application, I'm asked to enter a calculation which is evaluated, interupted twice by a breakpoint at line 9.
Enter code: 1+2 3 Enter code: 4+4 8
the test script
> cat ./calc_TRL.pl use Term::ReadLine; my $term = Term::ReadLine->new('Simple Perl calc'); my $prompt = "Enter code: "; my $OUT = $term->OUT || \*STDOUT; while ( $_ = $term->readline($prompt) ) { my $res = eval($_); warn $@ if $@; print $OUT $res, "\n" unless $@; $term->addhistory($_) if /\S/; }
tested with Term::ReadLine::Gnu installed.
generalisation
you can use this approach whenever you want the debugger communication separated into a separate term. e.g. Curses::UI comes to mind
discussion
the solution is not "perfect", of course you need to arrange the windows and switch with Alt-Tab between them. (maybe screen could solve this or an emacs inegration)
Furthermore you won't have a history with arrow navigation within the debugger, cause TRL was disabled.
another approach is to communicate via sockets with a debugger run within emacs, since emacs has it's own TRL-emulation this shouldn't interfere.
see also Re: Testing terminal programs within emacs (SOLVED) for an approach to handle all this automatically, by restarting a script with altered environment and different terminal.
TIMTOWTDI
see perldebguts , perldebtut and perldeb,
Also "Pro Perl Debugging" book and various TK tools on CPAN.
Cheers Rolf
(addicted to the Perl Programming Language and ☆☆☆☆ :)
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: How to perldebug a Term::ReadLine application (the other way round)
by LanX (Saint) on Dec 01, 2014 at 16:21 UTC | |
by RonW (Parson) on Dec 01, 2014 at 18:21 UTC | |
by LanX (Saint) on Dec 01, 2014 at 18:45 UTC | |
by RonW (Parson) on Dec 01, 2014 at 22:06 UTC |