Aliases: trace_back trace_length
Keywords:
### ** Examples # Trim backtraces automatically (this improves the generated # documentation for the rlang website and the same trick can be # useful within knitr documents): options(rlang_trace_top_env = current_env()) f <- function() g() g <- function() h() h <- function() trace_back() # When no lazy evaluation is involved the backtrace is linear # (i.e. every call has only one child) f()
▆ 1. └─f() 2. └─g() 3. └─h()
# Lazy evaluation introduces a tree like structure identity(identity(f()))
▆ 1. ├─base::identity(identity(f())) 2. ├─base::identity(f()) 3. └─f() 4. └─g() 5. └─h()
identity(try(f()))
▆ 1. ├─base::identity(try(f())) 2. ├─base::try(f()) 3. │ └─base::tryCatch(...) 4. │ └─base (local) tryCatchList(expr, classes, parentenv, handlers) 5. │ └─base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]]) 6. │ └─base (local) doTryCatch(return(expr), name, parentenv, handler) 7. └─f() 8. └─g() 9. └─h()
try(identity(f()))
▆ 1. ├─base::try(identity(f())) 2. │ └─base::tryCatch(...) 3. │ └─base (local) tryCatchList(expr, classes, parentenv, handlers) 4. │ └─base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]]) 5. │ └─base (local) doTryCatch(return(expr), name, parentenv, handler) 6. ├─base::identity(f()) 7. └─f() 8. └─g() 9. └─h()
# When printing, you can request to simplify this tree to only show # the direct sequence of calls that lead to `trace_back()` x <- try(identity(f())) x
▆ 1. ├─base::try(identity(f())) 2. │ └─base::tryCatch(...) 3. │ └─base (local) tryCatchList(expr, classes, parentenv, handlers) 4. │ └─base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]]) 5. │ └─base (local) doTryCatch(return(expr), name, parentenv, handler) 6. ├─base::identity(f()) 7. └─f() 8. └─g() 9. └─h()
print(x, simplify = "branch")
1. base::try(identity(f())) 7. f() 8. g() 9. h()
# With a little cunning you can also use it to capture the # tree from within a base NSE function x <- NULL with(mtcars, {x <<- f(); 10})
[1] 10
x
▆ 1. ├─base::with(...) 2. └─base::with.default(...) 3. └─base::eval(substitute(expr), data, enclos = parent.frame()) 4. └─base::eval(substitute(expr), data, enclos = parent.frame()) 5. └─f() 6. └─g() 7. └─h()
# Restore default top env for next example options(rlang_trace_top_env = NULL) # When code is executed indirectly, i.e. via source or within an # RMarkdown document, you'll tend to get a lot of guff at the beginning # related to the execution environment: conn <- textConnection("summary(f())") source(conn, echo = TRUE, local = TRUE)
> summary(f()) ▆ 1. ├─base::summary(f()) at conn:1:1 2. └─f() 3. └─g() 4. └─h()
close(conn) # To automatically strip this off, specify which frame should be # the top of the backtrace. This will automatically trim off calls # prior to that frame: top <- current_env() h <- function() trace_back(top) conn <- textConnection("summary(f())") source(conn, echo = TRUE, local = TRUE)
> summary(f()) ▆ 1. ├─base::summary(f()) at conn:1:1 2. └─f() 3. └─g() 4. └─h()
close(conn)