我希望能够找到.Deprecated
某个功能是否正在使用该功能,例如my.fun
。举个例子:
my.fun <- function (...) {
.Deprecated("my_fun")
my_fun(...)
}
目前我正在使用
grepl(".Deprecated", as.character(body(getFromNamespace("my.fun", "mypackage"))))
效果很好,在上面的示例中它返回
[1] FALSE TRUE FALSE
但是,如果我.Deprecated
在一个函数中将单词作为一个简单的字符串,则也会被选中。我知道mvbutils::foodweb()
和mvbutils::calleer.of()
函数,但只有在我明确定义自己的.Deprecated
函数时,它们才起作用。有没有人知道一种仅搜索函数而不是字符串的优雅方法?
一个健壮的解决方案必须检查函数体的语法,而不是进行字符串搜索。幸运的是,R使这个相对容易:
variables = all.names(body(myfunction))
'.Deprecated' %in% variables
需要注意的是,这并不能检验是否.Deprecated
真正指代base::.Deprecated
; 上面将显示将符号用作变量/函数名称的任何用法。但是,通常只有在不实际执行该功能的情况下,才能找到符号所指的功能,因此,这与所获得的效果一样好,而无需执行所有功能并跟踪其功能调用。
最好的办法是获取函数中使用的名称列表,并在定义函数的上下文中获取其定义。这可以看作是一种好的启发式方法:如果函数使用.Deprecated
,并且在定义函数的上下文中定义了该符号,则将产生正确的定义。但是,例如在以下情况下将失败:
假阳性:
f1 = function () {
.Deprecated = 42
}
假阴性:
f2 = function () {
x = get('.Deprecated', mode = 'function')
x("f1")
}
因此,请谨慎使用。
calls_function = function (f, target, target_name = deparse(substitute(target_name))) {
find_definition = function (candidates)
mget(candidates, environment(target), mode = 'function')
resolves_to_target = function (candidates)
sapply(find_definition(candidates), identical, target)
variables = unique(all.names(body(f)))
candidates = grep(target_name, variables, fixed = TRUE)
length(candidates) > 0 && any(resolves_to_target(variables[candidates]))
}
用法:
calls_function(f1, .Deprecated)
请注意,函数名称作为不带引号的参数传递。如果要传递base::.Deprecated
,还需要提供“ unqualified”名称作为第三个参数:
calls_function(f1, base::.Deprecated, '.Deprecated')
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句