In perl, what is the difference between $DB::single = 1 and 2?
Asked Answered
P

1

13

What is the difference between putting $DB::single=1 and $DB::single=2 in your code? Both seem to have the identical effect of halting execution at the statement following the assignment when I do a 'c' on the perl debugger command line.

perldebug says that a value of 1 is equivalent to having just pressed 's' to get to the next statement, and 2 is the same as 'n', but what difference does it make how you got to the statement?

Phonemic answered 20/12, 2010 at 11:42 Comment(0)
M
19

From perldebug:

If you set $DB::single to 2, it's equivalent to having just typed the n command (which executes over subroutine calls), whereas a value of 1 means the s command (which enters subroutine calls).

That much you know already.


From a user point of view, I'm pretty sure there is no difference. I base this on an examination of the actual DB.pm source code.

Let's follow this logically. You may want to refer to the source code. I've simplified some of the code to remove unnecessary detail but you should be able to get the idea from my descriptions.

When you are executing code in the debugger, there are (at least) two important variables, running and single. The combination of these is what decides whether code is run:

running  single  description
-------  ------  -----------
   0       ?     not running
   1       0     running flat-out
   1       1     single stepping, execute into function
   1       2     single stepping, execute over function

The DB() function is executed for every single line, and it contains the following snippet which will stop the running if single has been set (it always executes the current line regardless):

if ($DB::single) {
    $DB::single = 0;
    $running = 0;
}

That's why, if you set the variable in your Perl code, it will break (by break, I mean "stop running the code", not "damage somehow") the debugger at the next line.

When running is 0, the DB() function enters this little loop:

# Now sit in an event loop until something sets $running
do {
    $c->idle;          # call client event loop; must not block
} until $running;

In other words, it waits on a user command which sets running back to 1. This can be done by one of the following three functions:

sub next {
    $DB::single = 2;
    $running = 1;
}

sub step {
    $DB::single = 1;
    $running = 1;
}

sub cont {
    $DB::single = 0;
    $running = 1;
}

You can see that these three commands set up a different combination of single and running which will be used while executing the next Perl line (see the earlier table to see what these combinations mean).

The ability to use either 1 or 2 in your Perl code is a direct result of the fact that you're using a sneaky but clever trick to break execution from your Perl code itself, by setting a variable that would normally be set by a debugger command.

That's why it's not the value that matters so much as the fact you're forcing the debugger into a particular state.

Mccomb answered 20/12, 2010 at 11:46 Comment(1)
It may be well documented now but I'm of the opinion that it was a simple side effect of the way DB.pm worked, that someone discovered was useful (even if that someone was the original author). No-one in their right mind would design an API like this :-) They would have provided a function to do it so as to not expose the inner workings, not just let a variable be set to two different values, the difference between those values being absolutely nothing in terms of the use.Mccomb

© 2022 - 2024 — McMap. All rights reserved.