我不完全确定我理解
substitute
的作用,尽管我之前在它的代码中使用过。今天我在shiny::exprToFunction
中遇到了以下几行代码:
function (expr, env = parent.frame(2), quoted = FALSE, caller_offset = 1)
{
expr_sub <- eval(substitute(substitute(expr)),
...
}
有人可以解释一下为什么这里使用嵌套
substitute
吗?一个易于运行的示例确实会有帮助。
看一下
a<-function(aa) {
b(aa)
}
b<-function(bb) {
z(bb)
}
z<-function(zz) {
print(substitute(zz))
print(substitute(substitute(zz)))
print(eval(substitute(substitute(zz)), parent.frame()))
}
q<-5
a(q)
# bb
# substitute(bb)
# aa
第一个/内部替代获取传递给被调用函数的名称/符号。第二个/外部
substitute()
只是将 substitute()
命令包裹在发现的名称/符号周围。然后在它来自的父环境中评估 substitute()
。
使用
substitute
捕获变量名的方法仅在参数仍为 Promise 时有效;也就是说,它们尚未被评估。
文档解释了
substitute(expr)
的评估规则:
expr
,而是获取其解析树x
,如下所示:
x
在 [currentenv(), globalenv())
中未绑定 ⇒ x
x
绑定到一个promise ⇒promise 的表达式x
绑定到任何 obj ⇒ 解析后的 obj考虑这个例子
apply <- function (f, x) {
FUNNAME <- match.fun(f)
print(FUNNAME)
FUN <- eval(FUNNAME)
FUN(x)
}
match.fun <- function (FUN, descend=T) {
eval.parent(substitute(substitute(FUN)))
}
apply(sqrt, 2)
采用解析树/语言对象
substitute(FUN)
,用FUN
替换f
(promise中的表达式绑定到FUN
),产生语言对象substitute(f)
。
然后在
substitute(f)
的执行环境中评估apply
:
获取解析树 f
,用 f
替换 sqrt
,生成符号对象 sqrt
。
FUNNAME
与符号sqrt
绑定,剩下的就简单了