为什么`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属性而不是实际来源,但

  1. useSource=参数可用于指定实际功能源一起使用。它默认为 TRUE,但可以指定为 FALSE。
  2. body(f) 将显示实际的身体。
  3. 可以使用删除 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"


以上是为什么`print.function`不同意用`substitute()`创建的函数体?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>