On Thu, May 3, 2018 at 8:18 AM, Duncan Murdoch <murdoch.dun...@gmail.com> wrote: > On 03/05/2018 11:01 AM, William Dunlap via R-devel wrote: >> >> In R-3.5.0 you can use ...length(): >> > f <- function(..., n) ...length() >> > f(stop("one"), stop("two"), stop("three"), n=7) >> [1] 3 >> >> Prior to that substitute() is the way to go >> > g <- function(..., n) length(substitute(...())) >> > g(stop("one"), stop("two"), stop("three"), n=7) >> [1] 3 >> >> R-3.5.0 also has the ...elt(n) function, which returns >> the evaluated n'th entry in ... , without evaluating the >> other ... entries. >> > fn <- function(..., n) ...elt(n) >> > fn(stop("one"), 3*5, stop("three"), n=2) >> [1] 15 >> >> Prior to 3.5.0, eval the appropriate component of the output >> of substitute() in the appropriate environment: >> > gn <- function(..., n) { >> + nthExpr <- substitute(...())[[n]] >> + eval(nthExpr, envir=parent.frame()) >> + } >> > gn(stop("one"), environment(), stop("two"), n=2) >> <environment: R_GlobalEnv> >> > > Bill, the last of these doesn't quite work, because ... can be passed down > through a string of callers. You don't necessarily want to evaluate it in > the parent.frame(). For example: > > x <- "global" > f <- function(...) { > x <- "f" > g(...) > } > g <- function(...) { > firstExpr <- substitute(...())[[1]] > c(list(...)[[1]], eval(firstExpr, envir = parent.frame())) > } > > Calling g(x) correctly prints "global" twice, but calling f(x) incorrectly > prints > > [1] "global" "f" > > You can get the first element of ... without evaluating the rest using ..1, > but I don't know a way to do this for general n in pre-3.5.0 base R.
If you don't mind using a package: # works with R 3.1 and up library(rlang) x <- "global" f <- function(...) { x <- "f" g(...) } g <- function(...) { dots <- enquos(...) eval_tidy(dots[[1]]) } f(x, stop("!")) #> [1] "global" g(x, stop("!")) #> [1] "global" Hadley -- http://hadley.nz ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel