ctxt_stack() can be tricky to use in real code because all intervening frames are returned with the stack, including those at ctxt_stack() own call site. stack_trim() makes it easy to remove layers of intervening calls.

stack_trim(stack, n = 1)

Arguments

stack

An evaluation stack.

n

The number of call frames (not eval frames) to trim off the top of the stack. In other words, the number of layers of intervening frames to trim.

Examples

# Intervening frames appear on the evaluation stack: identity(identity(ctxt_stack()))
#> [[1]] #> <frame 33> (31) #> expr: identity(ctxt_stack()) #> env: [local 0x7f979d2a1bf8] #> #> [[2]] #> <frame 32> (31) #> expr: identity(identity(ctxt_stack())) #> env: [local 0x7f979d2a1a00] #> #> [[3]] #> <frame 31> (30) #> expr: eval(expr, envir, enclos) #> env: [local 0x7f979c531910] #> #> [[4]] #> <frame 30> (20) #> expr: eval(expr, envir, enclos) #> env: [local 0x7f979d1ab778] #> #> [[5]] #> <frame 29> (20) #> expr: withVisible(eval(expr, envir, enclos)) #> env: [local 0x7f979d1ab430] #> #> [[6]] #> <frame 28> (20) #> expr: withCallingHandlers(withVisible(eval(expr, envir, enclos)), warning = wHandler, <...> #> env: [local 0x7f979d47faa0] #> #> [[7]] #> <frame 27> (26) #> expr: doTryCatch(return(expr), name, parentenv, handler) #> env: [local 0x7f979d480ad8] #> #> [[8]] #> <frame 26> (25) #> expr: tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> env: [local 0x7f979d4806e8] #> #> [[9]] #> <frame 25> (24) #> expr: tryCatchList(expr, classes, parentenv, handlers) #> env: [local 0x7f979d484268] #> #> [[10]] #> <frame 24> (23) #> expr: tryCatch(expr, error = function(e) { <...> #> env: [local 0x7f979d4849c0] #> #> [[11]] #> <frame 23> (22) #> expr: try(f, silent = TRUE) #> env: [local 0x7f979d484720] #> #> [[12]] #> <frame 22> (20) #> expr: handle(ev <- withCallingHandlers(withVisible(eval(expr, envir, <...> #> env: [local 0x7f979d4853b8] #> #> [[13]] #> <frame 21> (20) #> expr: timing_fn(handle(ev <- withCallingHandlers(withVisible(eval(expr, <...> #> env: [local 0x7f979d4852a0] #> #> [[14]] #> <frame 20> (19) #> expr: evaluate_call(expr, parsed$src[[i]], envir = envir, enclos = enclos, <...> #> env: [frame 0x7f979d3d9c30] #> #> [[15]] #> <frame 19> (18) #> expr: evaluate::evaluate(text, code_env, new_device = TRUE) #> env: [frame 0x7f979f68ee30] #> #> [[16]] #> <frame 18> (16) #> expr: as_data.tag_examples(tags$tag_examples[[1]], env = new.env(parent = globalenv()), <...> #> env: [frame 0x7f97a005b808] #> #> [[17]] #> <frame 17> (16) #> expr: as_data(tags$tag_examples[[1]], env = new.env(parent = globalenv()), <...> #> env: [frame 0x7f97a0062238] #> #> [[18]] #> <frame 16> (12) #> expr: data_reference_topic(topic, pkg, path = path, examples = examples, <...> #> env: [frame 0x7f979c92e278] #> #> [[19]] #> <frame 15> (14) #> expr: stopifnot(is.list(x), is.list(val)) #> env: [frame 0x7f979c97dd18] #> #> [[20]] #> <frame 14> (13) #> expr: utils::modifyList(data, data_template(pkg, depth = depth)) #> env: [frame 0x7f979c97dab0] #> #> [[21]] #> <frame 13> (12) #> expr: render_page(pkg, "reference-topic", data = data_reference_topic(topic, <...> #> env: [frame 0x7f979d4cb158] #> #> [[22]] #> <frame 12> (11) #> expr: .f(.x[[i]], ...) #> env: [frame 0x7f97a1dc02e0] #> #> [[23]] #> <frame 11> (10) #> expr: purrr::map(., build_reference_topic, path, pkg = pkg, lazy = lazy, <...> #> env: [frame 0x7f979cbee238] #> #> [[24]] #> <frame 10> (8) #> expr: function_list[[k]](value) #> env: [frame 0x7f97a0d3fd10] #> #> [[25]] #> <frame 9> (8) #> expr: withVisible(function_list[[k]](value)) #> env: [frame 0x7f97a0d3fdf0] #> #> [[26]] #> <frame 8> (7) #> expr: freduce(value, `_function_list`) #> env: [frame 0x7f979f468918] #> #> [[27]] #> <frame 7> (6) #> expr: `_fseq`(`_lhs`) #> env: [frame 0x7f979f468ad8] #> #> [[28]] #> <frame 6> (5) #> expr: eval(expr, envir, enclos) #> env: [frame 0x7f97a0936408] #> #> [[29]] #> <frame 5> (3) #> expr: eval(quote(`_fseq`(`_lhs`)), env, env) #> env: [frame 0x7f979f468c98] #> #> [[30]] #> <frame 4> (3) #> expr: withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) #> env: [frame 0x7f97a0e1ff20] #> #> [[31]] #> <frame 3> (2) #> expr: pkg$topics %>% purrr::transpose() %>% purrr::map(build_reference_topic, <...> #> env: [frame 0x7f97a09367c0] #> #> [[32]] #> <frame 2> (1) #> expr: build_reference(pkg, lazy = FALSE, examples = examples, run_dont_run = run_dont_run, <...> #> env: [frame 0x7f97a07138e8] #> #> [[33]] #> <frame 1> (0) #> expr: pkgdown::build_site("/Users/lionel/Dropbox/R/hadley/rlang") #> env: [frame 0x7f97a457e3c8] #> #> [[34]] #> <frame 0> [global] #> expr: NULL #> env: [global] #> #> attr(,"class") #> [1] "ctxt_stack" "stack"
# stack_trim() will trim the first n layers of calls: stack_trim(identity(identity(ctxt_stack())))
#> [[1]] #> <frame 31> (30) #> expr: eval(expr, envir, enclos) #> env: [local 0x7f979c531910] #> #> [[2]] #> <frame 30> (20) #> expr: eval(expr, envir, enclos) #> env: [local 0x7f97a0e3aa08] #> #> [[3]] #> <frame 29> (20) #> expr: withVisible(eval(expr, envir, enclos)) #> env: [local 0x7f97a0e3ac70] #> #> [[4]] #> <frame 28> (20) #> expr: withCallingHandlers(withVisible(eval(expr, envir, enclos)), warning = wHandler, <...> #> env: [local 0x7f979f0164b0] #> #> [[5]] #> <frame 27> (26) #> expr: doTryCatch(return(expr), name, parentenv, handler) #> env: [local 0x7f979f016ad0] #> #> [[6]] #> <frame 26> (25) #> expr: tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> env: [local 0x7f979f582a70] #> #> [[7]] #> <frame 25> (24) #> expr: tryCatchList(expr, classes, parentenv, handlers) #> env: [local 0x7f979f582db8] #> #> [[8]] #> <frame 24> (23) #> expr: tryCatch(expr, error = function(e) { <...> #> env: [local 0x7f979f30eed8] #> #> [[9]] #> <frame 23> (22) #> expr: try(f, silent = TRUE) #> env: [local 0x7f979f30f0d0] #> #> [[10]] #> <frame 22> (20) #> expr: handle(ev <- withCallingHandlers(withVisible(eval(expr, envir, <...> #> env: [local 0x7f979b4382e8] #> #> [[11]] #> <frame 21> (20) #> expr: timing_fn(handle(ev <- withCallingHandlers(withVisible(eval(expr, <...> #> env: [local 0x7f979b438400] #> #> [[12]] #> <frame 20> (19) #> expr: evaluate_call(expr, parsed$src[[i]], envir = envir, enclos = enclos, <...> #> env: [frame 0x7f979f21a030] #> #> [[13]] #> <frame 19> (18) #> expr: evaluate::evaluate(text, code_env, new_device = TRUE) #> env: [frame 0x7f979f68ee30] #> #> [[14]] #> <frame 18> (16) #> expr: as_data.tag_examples(tags$tag_examples[[1]], env = new.env(parent = globalenv()), <...> #> env: [frame 0x7f97a005b808] #> #> [[15]] #> <frame 17> (16) #> expr: as_data(tags$tag_examples[[1]], env = new.env(parent = globalenv()), <...> #> env: [frame 0x7f97a0062238] #> #> [[16]] #> <frame 16> (12) #> expr: data_reference_topic(topic, pkg, path = path, examples = examples, <...> #> env: [frame 0x7f979c92e278] #> #> [[17]] #> <frame 15> (14) #> expr: stopifnot(is.list(x), is.list(val)) #> env: [frame 0x7f979c97dd18] #> #> [[18]] #> <frame 14> (13) #> expr: utils::modifyList(data, data_template(pkg, depth = depth)) #> env: [frame 0x7f979c97dab0] #> #> [[19]] #> <frame 13> (12) #> expr: render_page(pkg, "reference-topic", data = data_reference_topic(topic, <...> #> env: [frame 0x7f979d4cb158] #> #> [[20]] #> <frame 12> (11) #> expr: .f(.x[[i]], ...) #> env: [frame 0x7f97a1dc02e0] #> #> [[21]] #> <frame 11> (10) #> expr: purrr::map(., build_reference_topic, path, pkg = pkg, lazy = lazy, <...> #> env: [frame 0x7f979cbee238] #> #> [[22]] #> <frame 10> (8) #> expr: function_list[[k]](value) #> env: [frame 0x7f97a0d3fd10] #> #> [[23]] #> <frame 9> (8) #> expr: withVisible(function_list[[k]](value)) #> env: [frame 0x7f97a0d3fdf0] #> #> [[24]] #> <frame 8> (7) #> expr: freduce(value, `_function_list`) #> env: [frame 0x7f979f468918] #> #> [[25]] #> <frame 7> (6) #> expr: `_fseq`(`_lhs`) #> env: [frame 0x7f979f468ad8] #> #> [[26]] #> <frame 6> (5) #> expr: eval(expr, envir, enclos) #> env: [frame 0x7f97a0936408] #> #> [[27]] #> <frame 5> (3) #> expr: eval(quote(`_fseq`(`_lhs`)), env, env) #> env: [frame 0x7f979f468c98] #> #> [[28]] #> <frame 4> (3) #> expr: withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) #> env: [frame 0x7f97a0e1ff20] #> #> [[29]] #> <frame 3> (2) #> expr: pkg$topics %>% purrr::transpose() %>% purrr::map(build_reference_topic, <...> #> env: [frame 0x7f97a09367c0] #> #> [[30]] #> <frame 2> (1) #> expr: build_reference(pkg, lazy = FALSE, examples = examples, run_dont_run = run_dont_run, <...> #> env: [frame 0x7f97a07138e8] #> #> [[31]] #> <frame 1> (0) #> expr: pkgdown::build_site("/Users/lionel/Dropbox/R/hadley/rlang") #> env: [frame 0x7f97a457e3c8] #> #> [[32]] #> <frame 0> [global] #> expr: NULL #> env: [global] #> #> attr(,"class") #> [1] "ctxt_stack" "stack"
# Note that it also takes care of calls intervening at its own call # site: identity(identity( stack_trim(identity(identity(ctxt_stack()))) ))
#> [[1]] #> <frame 31> (30) #> expr: eval(expr, envir, enclos) #> env: [local 0x7f979c531910] #> #> [[2]] #> <frame 30> (20) #> expr: eval(expr, envir, enclos) #> env: [local 0x7f979f3fce60] #> #> [[3]] #> <frame 29> (20) #> expr: withVisible(eval(expr, envir, enclos)) #> env: [local 0x7f97a0ddef20] #> #> [[4]] #> <frame 28> (20) #> expr: withCallingHandlers(withVisible(eval(expr, envir, enclos)), warning = wHandler, <...> #> env: [local 0x7f97a0ddf508] #> #> [[5]] #> <frame 27> (26) #> expr: doTryCatch(return(expr), name, parentenv, handler) #> env: [local 0x7f97a0ddeb10] #> #> [[6]] #> <frame 26> (25) #> expr: tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> env: [local 0x7f97a0dddeb0] #> #> [[7]] #> <frame 25> (24) #> expr: tryCatchList(expr, classes, parentenv, handlers) #> env: [local 0x7f97a0dde1f8] #> #> [[8]] #> <frame 24> (23) #> expr: tryCatch(expr, error = function(e) { <...> #> env: [local 0x7f97a0ddd918] #> #> [[9]] #> <frame 23> (22) #> expr: try(f, silent = TRUE) #> env: [local 0x7f97a0dddb10] #> #> [[10]] #> <frame 22> (20) #> expr: handle(ev <- withCallingHandlers(withVisible(eval(expr, envir, <...> #> env: [local 0x7f97a0dddcd0] #> #> [[11]] #> <frame 21> (20) #> expr: timing_fn(handle(ev <- withCallingHandlers(withVisible(eval(expr, <...> #> env: [local 0x7f97a0ddce40] #> #> [[12]] #> <frame 20> (19) #> expr: evaluate_call(expr, parsed$src[[i]], envir = envir, enclos = enclos, <...> #> env: [frame 0x7f979f279e00] #> #> [[13]] #> <frame 19> (18) #> expr: evaluate::evaluate(text, code_env, new_device = TRUE) #> env: [frame 0x7f979f68ee30] #> #> [[14]] #> <frame 18> (16) #> expr: as_data.tag_examples(tags$tag_examples[[1]], env = new.env(parent = globalenv()), <...> #> env: [frame 0x7f97a005b808] #> #> [[15]] #> <frame 17> (16) #> expr: as_data(tags$tag_examples[[1]], env = new.env(parent = globalenv()), <...> #> env: [frame 0x7f97a0062238] #> #> [[16]] #> <frame 16> (12) #> expr: data_reference_topic(topic, pkg, path = path, examples = examples, <...> #> env: [frame 0x7f979c92e278] #> #> [[17]] #> <frame 15> (14) #> expr: stopifnot(is.list(x), is.list(val)) #> env: [frame 0x7f979c97dd18] #> #> [[18]] #> <frame 14> (13) #> expr: utils::modifyList(data, data_template(pkg, depth = depth)) #> env: [frame 0x7f979c97dab0] #> #> [[19]] #> <frame 13> (12) #> expr: render_page(pkg, "reference-topic", data = data_reference_topic(topic, <...> #> env: [frame 0x7f979d4cb158] #> #> [[20]] #> <frame 12> (11) #> expr: .f(.x[[i]], ...) #> env: [frame 0x7f97a1dc02e0] #> #> [[21]] #> <frame 11> (10) #> expr: purrr::map(., build_reference_topic, path, pkg = pkg, lazy = lazy, <...> #> env: [frame 0x7f979cbee238] #> #> [[22]] #> <frame 10> (8) #> expr: function_list[[k]](value) #> env: [frame 0x7f97a0d3fd10] #> #> [[23]] #> <frame 9> (8) #> expr: withVisible(function_list[[k]](value)) #> env: [frame 0x7f97a0d3fdf0] #> #> [[24]] #> <frame 8> (7) #> expr: freduce(value, `_function_list`) #> env: [frame 0x7f979f468918] #> #> [[25]] #> <frame 7> (6) #> expr: `_fseq`(`_lhs`) #> env: [frame 0x7f979f468ad8] #> #> [[26]] #> <frame 6> (5) #> expr: eval(expr, envir, enclos) #> env: [frame 0x7f97a0936408] #> #> [[27]] #> <frame 5> (3) #> expr: eval(quote(`_fseq`(`_lhs`)), env, env) #> env: [frame 0x7f979f468c98] #> #> [[28]] #> <frame 4> (3) #> expr: withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) #> env: [frame 0x7f97a0e1ff20] #> #> [[29]] #> <frame 3> (2) #> expr: pkg$topics %>% purrr::transpose() %>% purrr::map(build_reference_topic, <...> #> env: [frame 0x7f97a09367c0] #> #> [[30]] #> <frame 2> (1) #> expr: build_reference(pkg, lazy = FALSE, examples = examples, run_dont_run = run_dont_run, <...> #> env: [frame 0x7f97a07138e8] #> #> [[31]] #> <frame 1> (0) #> expr: pkgdown::build_site("/Users/lionel/Dropbox/R/hadley/rlang") #> env: [frame 0x7f97a457e3c8] #> #> [[32]] #> <frame 0> [global] #> expr: NULL #> env: [global] #> #> attr(,"class") #> [1] "ctxt_stack" "stack"
# It is especially useful when used within a function that needs to # inspect the evaluation stack but should nonetheless be callable # within nested calls without side effects: stack_util <- function() { # n = 2 means that two layers of intervening calls should be # removed: The layer at ctxt_stack()'s call site (including the # stack_trim() call), and the layer at stack_util()'s call. stack <- stack_trim(ctxt_stack(), n = 2) stack } user_fn <- function() { # A user calls your stack utility with intervening frames: identity(identity(stack_util())) } # These intervening frames won't appear in the evaluation stack identity(user_fn())
#> [[1]] #> <frame 33> (31) #> expr: user_fn() #> env: [local 0x7f97a0bc8e98] #> #> [[2]] #> <frame 32> (31) #> expr: identity(user_fn()) #> env: [local 0x7f97a0bc8e28] #> #> [[3]] #> <frame 31> (30) #> expr: eval(expr, envir, enclos) #> env: [local 0x7f979c531910] #> #> [[4]] #> <frame 30> (20) #> expr: eval(expr, envir, enclos) #> env: [local 0x7f97a0bc8c68] #> #> [[5]] #> <frame 29> (20) #> expr: withVisible(eval(expr, envir, enclos)) #> env: [local 0x7f97a0bc8a00] #> #> [[6]] #> <frame 28> (20) #> expr: withCallingHandlers(withVisible(eval(expr, envir, enclos)), warning = wHandler, <...> #> env: [local 0x7f979f00f518] #> #> [[7]] #> <frame 27> (26) #> expr: doTryCatch(return(expr), name, parentenv, handler) #> env: [local 0x7f979f32a468] #> #> [[8]] #> <frame 26> (25) #> expr: tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> env: [local 0x7f979f32a0b0] #> #> [[9]] #> <frame 25> (24) #> expr: tryCatchList(expr, classes, parentenv, handlers) #> env: [local 0x7f979f54fd10] #> #> [[10]] #> <frame 24> (23) #> expr: tryCatch(expr, error = function(e) { <...> #> env: [local 0x7f97a0b39f80] #> #> [[11]] #> <frame 23> (22) #> expr: try(f, silent = TRUE) #> env: [local 0x7f97a0b39d50] #> #> [[12]] #> <frame 22> (20) #> expr: handle(ev <- withCallingHandlers(withVisible(eval(expr, envir, <...> #> env: [local 0x7f97a0b39b58] #> #> [[13]] #> <frame 21> (20) #> expr: timing_fn(handle(ev <- withCallingHandlers(withVisible(eval(expr, <...> #> env: [local 0x7f97a0a6b378] #> #> [[14]] #> <frame 20> (19) #> expr: evaluate_call(expr, parsed$src[[i]], envir = envir, enclos = enclos, <...> #> env: [frame 0x7f97a0aec878] #> #> [[15]] #> <frame 19> (18) #> expr: evaluate::evaluate(text, code_env, new_device = TRUE) #> env: [frame 0x7f979f68ee30] #> #> [[16]] #> <frame 18> (16) #> expr: as_data.tag_examples(tags$tag_examples[[1]], env = new.env(parent = globalenv()), <...> #> env: [frame 0x7f97a005b808] #> #> [[17]] #> <frame 17> (16) #> expr: as_data(tags$tag_examples[[1]], env = new.env(parent = globalenv()), <...> #> env: [frame 0x7f97a0062238] #> #> [[18]] #> <frame 16> (12) #> expr: data_reference_topic(topic, pkg, path = path, examples = examples, <...> #> env: [frame 0x7f979c92e278] #> #> [[19]] #> <frame 15> (14) #> expr: stopifnot(is.list(x), is.list(val)) #> env: [frame 0x7f979c97dd18] #> #> [[20]] #> <frame 14> (13) #> expr: utils::modifyList(data, data_template(pkg, depth = depth)) #> env: [frame 0x7f979c97dab0] #> #> [[21]] #> <frame 13> (12) #> expr: render_page(pkg, "reference-topic", data = data_reference_topic(topic, <...> #> env: [frame 0x7f979d4cb158] #> #> [[22]] #> <frame 12> (11) #> expr: .f(.x[[i]], ...) #> env: [frame 0x7f97a1dc02e0] #> #> [[23]] #> <frame 11> (10) #> expr: purrr::map(., build_reference_topic, path, pkg = pkg, lazy = lazy, <...> #> env: [frame 0x7f979cbee238] #> #> [[24]] #> <frame 10> (8) #> expr: function_list[[k]](value) #> env: [frame 0x7f97a0d3fd10] #> #> [[25]] #> <frame 9> (8) #> expr: withVisible(function_list[[k]](value)) #> env: [frame 0x7f97a0d3fdf0] #> #> [[26]] #> <frame 8> (7) #> expr: freduce(value, `_function_list`) #> env: [frame 0x7f979f468918] #> #> [[27]] #> <frame 7> (6) #> expr: `_fseq`(`_lhs`) #> env: [frame 0x7f979f468ad8] #> #> [[28]] #> <frame 6> (5) #> expr: eval(expr, envir, enclos) #> env: [frame 0x7f97a0936408] #> #> [[29]] #> <frame 5> (3) #> expr: eval(quote(`_fseq`(`_lhs`)), env, env) #> env: [frame 0x7f979f468c98] #> #> [[30]] #> <frame 4> (3) #> expr: withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) #> env: [frame 0x7f97a0e1ff20] #> #> [[31]] #> <frame 3> (2) #> expr: pkg$topics %>% purrr::transpose() %>% purrr::map(build_reference_topic, <...> #> env: [frame 0x7f97a09367c0] #> #> [[32]] #> <frame 2> (1) #> expr: build_reference(pkg, lazy = FALSE, examples = examples, run_dont_run = run_dont_run, <...> #> env: [frame 0x7f97a07138e8] #> #> [[33]] #> <frame 1> (0) #> expr: pkgdown::build_site("/Users/lionel/Dropbox/R/hadley/rlang") #> env: [frame 0x7f97a457e3c8] #> #> [[34]] #> <frame 0> [global] #> expr: NULL #> env: [global] #> #> attr(,"class") #> [1] "ctxt_stack" "stack"