用 Sys.setenv 中的 rlang tidyeval 替换 `=` 运算符中的 LHS [英] substitute LHS in `=` operator with rlang tidyeval inside Sys.setenv

查看:74
本文介绍了用 Sys.setenv 中的 rlang tidyeval 替换 `=` 运算符中的 LHS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题描述

Sys.setenv 没有一个简单的接口来提供 LHS(环境变量名称)作为参数.如果要动态定义应该设置什么 env var,则需要元编程方法.

Sys.setenv does not have an easy interface to supply LHS (the env var name) as a parameter. If one wants to dynamically define what env var should be set, then metaprogramming approach is required.

基础 R 方式

这个小辅助函数按预期工作.

This small helper function works as expected.

setenv = function(var, value, quiet=TRUE) {
  stopifnot(is.character(var), !is.na(var), length(value)==1L, is.atomic(value))
  qc = as.call(c(list(quote(Sys.setenv)), setNames(list(value), var)))
  if (!quiet) print(qc)
  eval(qc)
}

var_name = "RISCOOL"
Sys.getenv(var_name)
#[1] ""
setenv(var_name, value=150, quiet=FALSE)
#Sys.setenv(RISCOOL = 150)
Sys.getenv(var_name)
#[1] "150"

问题

问题是如何使用pryrrlang (tidyeval)?或者最终是另一个流行的.
我根本不知道这些包,想更好地了解它们如何简化我的元编程代码.

The question is about how the problem can be solved using packages like pryr or rlang (tidyeval)? or eventually another popular one.
I don't know these packages at all and would like to get better understanding how they could simplify my metaprogramming code.

注意这个问题是关于元编程的,设置 env var 只是一个例子.

Note that question is about metaprogramming, setting env var is just an example.

推荐答案

如果要使用 rlang 风格的 quasiquotation 构造调用并直接求值,则需要 blast()

If you want to use rlang-style quasiquotation to construct a call and directly evaluate, you need blast()

blast <- function(expr, env = caller_env()) {
  eval_bare(enexpr(expr), env)
}

vars <- c(A = "a", B = "b", C = "c")

blast(data.frame(!!!vars))
#>   A B C
#> 1 a b c

在您的原始示例中,您需要取消引用名称.我们尚不支持对 := 的 LHS 进行深度取消引用(请参阅 https://github.com/r-lib/rlang/issues/279),但您可以使用 !!! 代替:

In your original example you need to unquote a name. We don't support deep-unquoting on the LHS of := yet (see https://github.com/r-lib/rlang/issues/279), but you can use !!! instead:

setenv <- function(var, value) {
  args <- setNames(value, var)
  blast(Sys.setenv(!!!args))
}

setenv("foobar", 1)
#> [1] TRUE

Sys.getenv("foobar")
#> [1] "1"

要插入打印的调用,blast 级别太高,但您可以使用组件:

To insert the printed call, blast is too high level but you can use the components:

setenv <- function(var, value, quiet = FALSE) {
  args <- setNames(value, var)
  call <- expr(Sys.setenv(!!!args))

  if (!quiet) {
    print(call)
  }

  # Evaluate in our own environment where `Sys.setenv()` is defined
  # (and protected if we're in a package namespace)
  eval(call)
}

这篇关于用 Sys.setenv 中的 rlang tidyeval 替换 `=` 运算符中的 LHS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆