summaryrefslogtreecommitdiff
path: root/lib/perl5db.t
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-07-13 11:41:44 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-07-13 11:49:14 -0700
commitbf2614180a655fadfe4ad9de9bbcf01c42b29e7e (patch)
tree3f3869bd576d4ed5812f911e1863d2b9bc6fde1e /lib/perl5db.t
parentc4a26ef3f320212167cfd6d700bfcc92f04a6939 (diff)
downloadperl-bf2614180a655fadfe4ad9de9bbcf01c42b29e7e.tar.gz
[perl #118839] Make ā€˜nā€™ debugger cmd respect lv subs
The ā€˜nā€™ debugger command, which is supposed to step over subs, was not stepping over lvalue subs. This is a regression from 5.8, but 5.8 was worse. This bug did not occur in 5.8 because there was no mechanism back then for handling lvalue subs specially (via DB::lsub), so assignment to an lvalue sub was completely broken under the debugger. Perl 5.10 introduced DB::lsub. The implementation in perl5db.pl contains these lines at the end of the sub: # Pop the single-step value back off the stack. $single |= $stack[ $stack_depth-- ]; # call the original lvalue sub. &$sub; The regular DB::sub does this: { no strict 'refs'; @ret = &$sub; } # Pop the single-step value back off the stack. $single |= $stack[ $stack_depth-- ]; Notice how $single (i.e., $DB::single) is modified before and after the sub call, respectively. The order is different. There are two types of lvalue list context for lvalue subs. (foo)=3 will allow sub foo:lvalue{@a} to return the array itself. \(foo) and bar(foo) will flatten the array. So there is no way in pure Perl to capture the return value and have it returned to the caller unchanged. That is why DB::lsub has to call the sub last of all (and have the context propagated). The solution here is to use localisation to accomplish the assigment to $single after the lvalue sub exits.
Diffstat (limited to 'lib/perl5db.t')
-rw-r--r--lib/perl5db.t16
1 files changed, 15 insertions, 1 deletions
diff --git a/lib/perl5db.t b/lib/perl5db.t
index 6ab4694608..26b0581c89 100644
--- a/lib/perl5db.t
+++ b/lib/perl5db.t
@@ -29,7 +29,7 @@ BEGIN {
$ENV{PERL_RL} = 'Perl'; # Suppress system Term::ReadLine::Gnu
}
-plan(116);
+plan(117);
my $rc_filename = '.perldb';
@@ -1044,6 +1044,20 @@ sub _calc_trace_wrapper
);
}
+# Test for n with lvalue subs
+DebugWrap->new({
+ cmds =>
+ [
+ 'n', 'print "<$x>"',
+ 'n', 'print "<$x>"',
+ 'q',
+ ],
+ prog => '../lib/perl5db/t/lsub-n',
+})->output_like(
+ qr/<1><11>/,
+ 'n steps over lvalue subs',
+);
+
# Test for 'M' (module list).
{
my $wrapper = DebugWrap->new(