我正在尝试在R中找到isdebugged()
的全局副本。我的场景是我有调用其他函数的函数,所有这些都是我编写的,我正在转向{{1}在我的调试过程中打开和关闭不同的功能。但是,我可能会忘记将哪些功能设置为要调试。当我忘记并开始循环时,我可能会得到更多的输出(令人讨厌,但并不可怕),或者当某些需要时(不好)我可能没有输出。
我目前的方法是使用类似于下面的函数,我可以用debug()
调用它或列出已加载库中的项目(下面的示例)。这可能就足够了,但它要求我用工作区中的每个函数列表或加载的包中调用它。我可以包装另一个获取这些功能的函数。似乎应该有一种更简单的方法来直接“询问”调试函数或查询环境的一些模糊部分,它隐藏了设置了调试标志的函数列表。
所以,这是一个两部分的问题:
我意识到我可以尝试另一种方法,即将listDebugged(ls())
和debug
包含在也维护隐藏的调试函数名列表的函数中。我还不相信这是安全的事情。
更新(2011年8月5日):我搜索了SO,但没有找到早先的问题。然而,SO的“相关问题”列表显示an earlier question that is similar,尽管该问题的答案中的函数比@cbeleites提供的函数更冗长,更慢。较旧的问题也没有提供任何代码,而我做了。 :)
代码:
undebug
答案 0 :(得分:6)
这是我对listDebugged函数的抛出:
ls.deb <- function(items = search ()){
.ls.deb <- function (i){
f <- ls (i)
f <- mget (f, as.environment (i), mode = "function",
## return a function that is not debugged
ifnotfound = list (function (x) function () NULL)
)
if (length (f) == 0)
return (NULL)
f <- f [sapply (f, isdebugged)]
f <- names (f)
## now check whether the debugged function is masked by a not debugged one
masked <- !sapply (f, function (f) isdebugged (get (f)))
## generate pretty output format:
## "package::function" and "(package::function)" for masked debugged functions
if (length (f) > 0) {
if (grepl ('^package:', i)) {
i <- gsub ('^package:', '', i)
f <- paste (i, f, sep = "::")
}
f [masked] <- paste ("(", f [masked], ")", sep = "")
f
} else {
NULL
}
}
functions <- lapply (items, .ls.deb)
unlist (functions)
}
package::function
(或者更确切地说是namespace::function
,但无论如何包都会很快拥有名称空间)。 "(package::function)"
答案 1 :(得分:3)
这是一个简单的单行使用lsf.str
:
which(sapply(lsf.str(), isdebugged))
您可以更改函数中的环境,有关更多参数,请参阅?lsf.str
。
答案 2 :(得分:2)
自从最初的问题以来,我一直在寻找越来越多的Mark Bravington's debug
package。如果使用该包,则check.for.traces()
是列出通过mtrace
调试的那些函数的适当命令。
如果花了很多时间使用R调试器和各种trace
选项,那么调试包值得一看。
答案 3 :(得分:1)
@cbeleites我喜欢你的答案,但它对我没用。我得到了它的工作,但它没有你的功能(没有递归检查,没有漂亮的打印)
require(plyr)
debug.ls <- function(items = search()){
.debug.ls <- function(package){
f <- ls(package)
active <- f[which(aaply(f, 1, function(x){
tryCatch(isdebugged(x), error = function(e){FALSE}, finally=FALSE)
}))]
if(length(active)==0){
return(NULL)
}
active
}
functions <- lapply (items, .debug.ls)
unlist (functions)
}
答案 4 :(得分:0)
由于未能 undebug 功能,我不断陷入browser
窗口框架。所以我创建了两个函数并将它们添加到我的.Rprofile
。辅助函数非常简单。
require(logging)
# Returns a vector of functions on which the debug flag is set
debuggedFuns <- function() {
envs <- search()
debug_vars <- sapply(envs, function(each_env) {
funs <- names(Filter(is.function, sapply(ls(each_env), get, each_env)))
debug_funs <- Filter(isdebugged, funs)
debug_funs
})
return(as.vector(unlist(debug_vars)))
}
# Removes the debug flag from all the functions returned by `debuggedFuns`
unDebugAll <- function(verbose = TRUE) {
toUnDebug <- debuggedFuns()
if (length(toUnDebug) == 0) {
if (verbose) loginfo('no Functions to `undebug`')
return(invisible())
} else {
if (verbose) loginfo('undebugging [%s]', paste0(toUnDebug, collapse = ', '))
for (each_fn in toUnDebug) {
undebug(each_fn)
}
return(invisible())
}
}
我已经测试了它们,它运行得很好。希望这有帮助!