为什么`print.function`不同意用`substitute()`创建的函数体?
在 R 中,可以在执行一段代码之前进行“宏替换”。使用这种技术,可以在实际创建函数之前动态地将常量嵌入到函数体中,从而避免变量查找:
expr = substitute(function () s, list('s'='ABCDE'))
f = eval(expr)
f()
# [1] "ABCDE"
environment(f)
# <environment: R_GlobalEnv>
这里,封闭环境是R_GlobalEnv,它根本不包含变量s,但函数仍然可以"ABCDE"正确返回。这似乎意味着返回的字符串"ABCDE"确实不是来自变量查找,而是嵌入到函数体中。
但是现在如果你打印函数,你可以看到它s仍然存在,虽然它不在expr:
print(f)
# function () s
print(expr)
# function() "ABCDE"
这里到底发生了什么?
回答
print.function打印srcref属性而不是实际来源,但
- 该
useSource=参数可用于指定实际功能源一起使用。它默认为 TRUE,但可以指定为 FALSE。 body(f)将显示实际的身体。- 可以使用删除 srcref 属性,
attr(f, "srcref") <- NULL在这种情况下 print 将显示实际来源。也可以覆盖 srcref 属性。attr(f, "srcref") <- format(f)之所以有效,是因为format使用了实际来源。
这是一个演示。
expr <- substitute(function () s, list('s'='ABCDE'))
f <- eval(expr)
f
## function () s
print(f)
## function () s
print(f, useSource = FALSE)
## function ()
## "ABCDE"
attr(f, "srcref")
## function () s
body(f)
## [1] "ABCDE"
format(f)
## [1] "function () " ""ABCDE""
f <- eval(expr)
attr(f, "srcref") <- NULL
f
## function ()
## "ABCDE"
f <- eval(expr)
attr(f, "srcref") <- format(f)
f
## function ()
## "ABCDE"
THE END
二维码