R:测试函数从封闭环境中获取哪些对象

Flo*_*ian 5 testing debugging environment r function

定义R函数时,有时会想不到它依赖于封闭环境中的对象。就像是:

a <- 1
fn <- function(x) x + a
Run Code Online (Sandbox Code Playgroud)

如果这是无意发生的,则可能导致难以调试的问题。

有没有简单的方法可以测试是否fn使用封闭环境中的对象?

就像是:

test(fn=fn, args=list(x=1))
## --> uses 'a' from enclosing environment
Run Code Online (Sandbox Code Playgroud)

div*_*san 3

一种可能性是使用包findGlobals中的函数,codetools该函数旨在:

查找闭包使用的全局函数和变量

这在您的示例中有效:

#install.packages('codetools')
codetools::findGlobals(fn)
[1] "+" "a"
Run Code Online (Sandbox Code Playgroud)

如果我们a在函数内部定义,它就会消失:

fn <- function(x) {
    a = 1
    x + a
}

codetools::findGlobals(fn)
[1] "{" "+" "="
Run Code Online (Sandbox Code Playgroud)

但我还没有在任何更复杂的事情中使用过它,所以我不能说它对于更复杂的函数会有多准确。该文档附带以下警告:

结果是一个近似值。R 语义仅允许识别可能是本地的变量(以及假设不使用 allocate 和 rm 的事件)。