R - 取代来自globalenv的promise表达式

时间:2014-10-15 00:20:26

标签: r promise substitution

>#R version 3.1.1 (2014-07-10) -- "Sock it to Me"
> library(pryr)
> f1 <- function() { cat("hi1\n"); 1 }
> f2 <- function() { cat("hi2\n"); 2 }

这是我想要的,但e = globalenv

> e <- new.env()
> delayedAssign("x", f1(), assign.env = e)
> substitute(x, e)
f1()

如果我尝试substitute它不起作用(根据文档,substitute中没有globalenv):

> delayedAssign("x", f1(), assign.env = globalenv())
> substitute(x, globalenv())
x
来自subs

pryr无法正常工作,因为它会评估承诺:

> subs(x, globalenv())
hi1
[1] 1

实际上它会评估所有承诺,因为它会将globalenv转换为列表:

> delayedAssign("x", f1(), assign.env = globalenv())
> delayedAssign("y", f2(), assign.env = globalenv())
> subs(x, globalenv())
hi1
hi2
[1] 1
> 

总结:是否有可能在substitute等所有环境中都使用globalenv这样的承诺?

更新

我无法弄清楚如何在R中做到这一点,所以我写了(更确切地说是从R代码中提取)以下C函数

SEXP get_no_eval(SEXP symbol, SEXP envir) {
  SEXP t;

  if (!Rf_isString(symbol) || Rf_length(symbol)!=1) 
    Rf_error("symbol is not a string");

  if (!Rf_isEnvironment(envir)) 
    Rf_error("envir is not an environment");

  if (envir==R_NilValue) 
    Rf_error("envir is NULL");

  t = Rf_findVar(Rf_install(CHAR(STRING_ELT(symbol, 0))), envir);
  if (t != R_UnboundValue) {
    if (TYPEOF(t) == PROMSXP) {
      do {
        t = PREXPR(t);
      } while(TYPEOF(t) == PROMSXP);
      if (NAMED(t) < 2) SET_NAMED(t, 2);
      return t;
    }
    else if (TYPEOF(t) == DOTSXP)
      Rf_error("'...' used in an incorrect context");
    return t;
  }

  Rf_error("symbol not found");
  return R_NilValue;
}

现在,我可以继续上面的例子:

> delayedAssign("x", f1(), assign.env = globalenv())
> get_no_eval("x", globalenv())
f1()

不完全是substitute,但可以满足我的需要。

0 个答案:

没有答案