I want to find the environment from which ...call arguments (points) arise .
Scenario
For example, consider a function
foo <- function(x, ...) {
}
We need a function env_dots()that we call from foo()that finds the source environment ...in the call foo(), even when the call is foo()deeply nested. That is, if we define
foo <- function(x, ...) {
env <- env_dots()
}
and insert a call foofor example
baz <- function(...) {
a <- "You found the dots"
bar(1, 2)
}
bar <- function(...)
foo(...)
then the call baz()should return the environment in which it arises ...in the (nested) call foo(...): this is the environment in which the call is made bar(1, 2), because 2(but not 1) it is passed to the points foo. In particular, we should get
baz()$a
Naive implementation env_dots()
- env_dots(), , , ... , .
env_dots():
env_dots <- function(mc) {
if (!rlang::has_name(mc, "...")) return(NULL)
stack <- rlang::call_stack()[-1]
l <- length(stack)
i <- 1
while (i <= l && has_dots(stack[[i]]$expr)) i <- i + 1
if (i <= l) stack[[i + 1]]$env else NULL
}
has_dots <- function(x) {
if (is.null(x))
return(FALSE)
args <- rlang::lang_tail(x)
any(vapply(args, identical, logical(1), y = quote(...)))
}
:
foo <- function(x, ...)
env_dots(match.call(expand.dots = FALSE))
baz()$a
bar(1, 2)
bar(1)
env_dots() .
. rlang::quos(...), quosures (, ).