41;309;0c> Why does debug() enter Browse[3] here at all, and why does it happen the> first time and not the second? This seems unexpected to me, and has > undesirable effects for ESS users (that I reported here - > https://stat.ethz.ch/pipermail/ess-help/2013-June/009154.html - but just > realized my post to r-devel didn't make it through when I tried to report > it back then). > > > Fun <- function(n) print(n) > > debug(Fun) > > Fun(2) > debugging in: Fun(2) > debug: print(n) > Browse[2]> {n+2} > debug at #1: n + 2I think this is the result of debugging being implemented by setting a flag in the environment of the function being debugged. That's how the debug status gets passed on to inner statements. Your {n+2} expression looks like an inner statement, and of course has the environment of the call of Fun. (In contrast, (n+2) doesn't do this, because "(" doesn't check for debugging.) You could avoid it with some hack like using (function(){n+2})() rather than {n+2}. (I'm assuming there's some reason you're not just using (n+2), with parentheses rather than curly brackets). I've considered changing how this works in pqR, using pqR's "variant return" mechanism to pass on the information that an inner statement should be debugged. This would also allow one to avoid entering the debugger for "if" when it is used as an expression rather than a statement (for example, a <- if (x>0) 3 else 4). Radford Neal
Duncan Murdoch
2015-Jan-01 16:00 UTC
[Rd] Unexpected behavior of debug() in step-wise mode
On 01/01/2015 9:49 AM, Radford Neal wrote:> 41;309;0c> Why does debug() enter Browse[3] here at all, and why does it happen the >> first time and not the second? This seems unexpected to me, and has >> undesirable effects for ESS users (that I reported here - >> https://stat.ethz.ch/pipermail/ess-help/2013-June/009154.html - but just >> realized my post to r-devel didn't make it through when I tried to report >> it back then). >> >>> Fun <- function(n) print(n) >>> debug(Fun) >>> Fun(2) >> debugging in: Fun(2) >> debug: print(n) >> Browse[2]> {n+2} >> debug at #1: n + 2 > > I think this is the result of debugging being implemented by setting > a flag in the environment of the function being debugged. That's how > the debug status gets passed on to inner statements. Your {n+2} > expression looks like an inner statement, and of course has the > environment of the call of Fun. (In contrast, (n+2) doesn't do this, > because "(" doesn't check for debugging.)That makes sense, and suggests a simple fix: when evaluating an expression typed by the user at the prompt, temporarily turn off the debug flag on the environment. I'll try this out, but the trouble with changes to the debugger is that most changes are hard to test, since they depend on user interaction. It's very easy to make a change that fixes one problem and causes another.> > You could avoid it with some hack like using (function(){n+2})() > rather than {n+2}. (I'm assuming there's some reason you're not > just using (n+2), with parentheses rather than curly brackets). > > I've considered changing how this works in pqR, using pqR's "variant > return" mechanism to pass on the information that an inner statement > should be debugged. This would also allow one to avoid entering the > debugger for "if" when it is used as an expression rather than a > statement (for example, a <- if (x>0) 3 else 4).I'd rather not make that change. In the example you give it makes sense, but what about if you replace the 3 and 4 with more substantial braced expressions? Then I'd probably want to step into whichever block got chosen.>From the interpreter's point of view, there's really little differencebetween "if" as an expression and "if" as a statement. In both cases it needs to treat it as an expression with a value (because statement values are returned as the value of functions or braced blocks). Duncan Murdoch