Closed pnacht closed 3 years ago
As documented, with_env()
is experimental. I think I'll just deprecate it now.
Note that if you want to use quosures, you'll need the environment to be a data mask. And use eval_tidy()
, which with_env()
doesn't.
set_in_env <- function(expr) {
expr <- enquo(expr)
expr <- expr({
!!expr
x <- 1
environment()
})
eval_tidy(expr)
}
e <- set_in_env(foo <- 2)
env_print(e)
#> <environment: 0x7fca55826510>
#> Parent: <environment: 0x7fca46733450>
#> Bindings:
#> • foo: <dbl>
#> • `~`: <fn>
#> • x: <dbl>
#> • .__tidyeval_quosure_mask__.: <env>
A data mask does not feel appropriate for this sort of function, so I'd remove quosures from the equation:
set_in_env <- function(expr, parent = caller_env()) {
expr <- enexpr(expr)
env <- env(parent, x = 1)
eval_bare(expr, env)
env
}
e <- set_in_env(foo <- 2)
env_print(e)
#> <environment: 0x7fca37d9c8f8>
#> Parent: <environment: global>
#> Bindings:
#> • x: <dbl>
#> • foo: <dbl>
By the way do you know about env_bind()
?
Reopening so I don't forget to deprecate.
with_env
allows us to evaluate expressions in an environment, including setting values in the environment:However, it doesn't support quasiquotation, which means we can't trivially write a function which takes an expression and evaluates it in an environment.
Created on 2021-10-26 by the reprex package (v2.0.1)
As mentioned by @MrFlick on SO, we can use
inject
to build the call:This works, but it feels like a workaround and not like the most proper and idiomatic way of doing it. Would allowing unquotation in
with_env
be possible or is there a reason for this that hasn't occurred to me?