Dear monks,
often when I debug functional style programs
(that is there are some greps and maps present), then I wished for some accelerated stepping in the debugger.
Example:
Instead of
main::(perldb_demo.pl:4): my @a = (1..10);
DB<1> n
main::(perldb_demo.pl:6): if (0 < scalar grep { $_ == 9 } @a) {
DB<1>
main::(perldb_demo.pl:6): if (0 < scalar grep { $_ == 9 } @a) {
DB<1>
main::(perldb_demo.pl:6): if (0 < scalar grep { $_ == 9 } @a) {
DB<1>
main::(perldb_demo.pl:6): if (0 < scalar grep { $_ == 9 } @a) {
DB<1>
main::(perldb_demo.pl:6): if (0 < scalar grep { $_ == 9 } @a) {
DB<1>
main::(perldb_demo.pl:6): if (0 < scalar grep { $_ == 9 } @a) {
DB<1>
main::(perldb_demo.pl:6): if (0 < scalar grep { $_ == 9 } @a) {
DB<1>
main::(perldb_demo.pl:6): if (0 < scalar grep { $_ == 9 } @a) {
DB<1>
main::(perldb_demo.pl:6): if (0 < scalar grep { $_ == 9 } @a) {
DB<1>
main::(perldb_demo.pl:6): if (0 < scalar grep { $_ == 9 } @a) {
DB<1>
main::(perldb_demo.pl:6): if (0 < scalar grep { $_ == 9 } @a) {
DB<1>
main::(perldb_demo.pl:7): print "found\n";
I would like to have
main::(perldb_demo.pl:4): my @a = (1..10);
DB<1> n
main::(perldb_demo.pl:6): if (0 < scalar grep { $_ == 9 } @a) {
DB<1>
main::(perldb_demo.pl:7): print "found\n";
So generally I would like to use
the debugger command 's' for
small steps/increments
and 'n' for bigger steps.
In the example above, if the original behavior is wanted, use the 's' command which still interrupts grep's code block for each element.
I asked Richard Foley about it, and he agreed
that this might be useful for other users as well. Also, modifying the 'n' command would make more sense
than to add a new command just for stepping over grep/map/sort and otherwise being identical to 'n'.
A possible danger of this change might be this: the actual involved looping is not visible anymore, leading to a false impression of efficiency.
So, I have made a patch for the debugger (Perl 5.10.0).
Currently the new code checks for grep/map/sort and in that case sets a temporary breakpoint like the 'c' command would do. Otherwise the old behavior is used.
Probably other operators (all, any, ...) from List::Util and List::MoreUtils would qualify also, but currently they are not part of the core.
Before I contact p5p, I would like to hear your opinions for this proposal.
Thanks for comments!
--- perl5db.pl.org 2007-12-18 10:47:07.000000000 +0100
+++ perl5db.pl 2008-09-01 23:02:16.718750000 +0200
@@ -2643,7 +2643,7 @@
demarcation' above which commands can be entered anytime, and below w
+hich
they can't.
-=head4 C<n> - single step, but don't trace down into subs
+=head4 C<n> - single step, but don't trace down into subs, and not ev
+en into grep/map/sort
Done by setting C<$single> to 2, which forces subs to execute straigh
+t through
when entered (see C<DB::sub>). We also save the C<n> command in C<$la
+ststep>,
@@ -2655,9 +2655,41 @@
$cmd =~ /^n$/ && do {
end_report(), next CMD if $finished and $level <=
+ 1;
- # Single step, but don't enter subs.
- $single = 2;
+ if ( $dbline[$line] =~ m{\b(
+ grep
+ |
+ map
+ |
+ sort)\b}xms
+ ) {
+ # Scan forward to the next executable lin
+e
+ $i = $line;
+ ++$i;
+ $max = $#dbline;
+ ++$i while $dbline[$i] == 0 && $i < $max;
+ # Check if we would leave the sub
+ my @sublast = split m{-}xms, $sub{$sub};
+ if (($sub eq '' || $i <= $sublast[-1])
+ && $dbline[$i] != 0) {
+ # Next line is in current sub
+ # or no sub at all
+
+ # Set up the one-time-break sigil.
+ $dbline{$i} =~ s/($|\0)/;9$1/; # add
+ one-time-only b.p.
+
+ # Clear single stepping flags
+ $DB::single &= ~3;
+ } else {
+ # have no line (oneliner)
+ # or about to leave the sub...
+ # Turn on stack tracing one level up.
+ $stack[ -1 ] |= 1;
+ }
+ } else {
+ # Single step, but don't enter subs.
+ $single = 2;
+ }
# Save for empty command (repeat last).
$laststep = $cmd;
last CMD;
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.