While all capturing functions in the tidy evaluation framework
perform unquote on capture (most notably quo()
),
expr_interp()
manually processes unquoting operators in
expressions that are already captured. expr_interp()
should be
called in all user-facing functions expecting a formula as argument
to provide the same quasiquotation functionality as NSE functions.
expr_interp(x, env = NULL)
x | A function, raw expression, or formula to interpolate. |
---|---|
env | The environment in which unquoted expressions should be evaluated. By default, the formula or closure environment if a formula or a function, or the current environment otherwise. |
# All tidy NSE functions like quo() unquote on capture: quo(list(!!(1 + 2))) #> <quosure> #> expr: ^list(3) #> env: 0x560eb0833ef8 # expr_interp() is meant to provide the same functionality when you # have a formula or expression that might contain unquoting # operators: f <- ~list(!!(1 + 2)) expr_interp(f) #> ~list(3) #> <environment: 0x560eb0833ef8> # Note that only the outer formula is unquoted (which is a reason # to use expr_interp() as early as possible in all user-facing # functions): f <- ~list(~!!(1 + 2), !!(1 + 2)) expr_interp(f) #> ~list(~3, 3) #> <environment: 0x560eb0833ef8> # Another purpose for expr_interp() is to interpolate a closure's # body. This is useful to inline a function within another. The # important limitation is that all formal arguments of the inlined # function should be defined in the receiving function: other_fn <- function(x) toupper(x) fn <- expr_interp(function(x) { x <- paste0(x, "_suffix") !!! body(other_fn) }) #> Warning: Unquoting language objects with `!!!` is deprecated as of rlang 0.4.0. #> Please use `!!` instead. #> #> # Bad: #> dplyr::select(data, !!!enquo(x)) #> #> # Good: #> dplyr::select(data, !!enquo(x)) # Unquote single quosure #> dplyr::select(data, !!!enquos(x)) # Splice list of quosures #> #> This warning is displayed once per session. fn #> function (x) #> { #> x <- paste0(x, "_suffix") #> toupper(x) #> } #> <environment: 0x560eb0833ef8> fn("foo") #> [1] "FOO_SUFFIX"