问题
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