How to start debugger only when condition is met

笑着哭i 提交于 2021-02-07 14:24:25

问题


Assume I have a function which uses a loop over integer i. Now something goes wrong and I assume the error happens when i=5. Now I can step through every single step (what I did up to now).

But now I read about the condition and text argument of browser and debug:

text a text string that can be retrieved when the browser is entered.
condition a condition that can be retrieved when the browser is entered.

Is it possible to use the arguments in a way it works as I want?

Here is an example. The debugger / browser should only start after i=5 is reached:

fun <- function(x, y, n) {
  result <- 0
  for (i in 1:n) {
    # browser(condition = (i == 5)) # does not work
    result <- result + i * ( x + y)
  }
  return(result)
}

x <- 2
y <- 3
n <- 10

# debug(fun, condition = (i == 5)) # does not work
debug(fun)
r <- fun(x, y, n)
print(r)

The solution

if (i == 5) { # inside loop of fun()
  browser()
}

is working, but I thougt there might be something better (No extra code inside the function)


回答1:


You can use the argument expr in browser():

fun <- function(x, y, n) {
  result <- 0
  for (i in 1:n) {
    browser(expr = {i == 5})
    result <- result + i * ( x + y)
  }
  return(result)
}

It will then only open the environment where browser() was called from if the expression evaluates to TRUE.

If you want to use debug():

debug(fun, condition = i == 5)

and then call the function:

fun <- function(x, y, n) {
  result <- 0
  for (i in 1:n) {
    result <- result + i * ( x + y)
  }
  return(result)
}

fun(x, y, n)



回答2:


Use advanced features of trace().

First, identify the line of your function to debug, following the help page instructions for the argument at =, leading to at = list(c(3, 4))

> as.list(body(fun))
[[1]]
`{`

[[2]]
result <- 0

[[3]]
for (i in 1:n) {
    result <- result + i * (x + y)
}

[[4]]
return(result)

> as.list(body(fun)[[3]])
[[1]]
`for`

[[2]]
i

[[3]]
1:n

[[4]]
{
    result <- result + i * (x + y)
}

Next, specify a conditional break point by providing as the tracer= argument an unevaluated expression that invokes the browser when a specific condition is met, tracer = quote(if (i == 3) browser())

So

> trace(fun, tracer = quote(if (i == 3) browser()), at=list(c(3, 4)), print=FALSE)
[1] "fun"
> r <- fun(x, y, n)
Called from: eval(expr, p)
Browse[1]> 
debug: {
    result <- result + i * (x + y)
}
Browse[2]>  i
[1] 3
Browse[2]> result
[1] 15
Browse[2]> 


来源:https://stackoverflow.com/questions/49008890/how-to-start-debugger-only-when-condition-is-met

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!