问题描述
考虑一下,我们已经调用了 debug()
的几个函数来在它们上创建断点。当我们找到并解决了该错误后,是否可以通过 debug()
标记 undebug()
单个命令?
Consider we have called debug()
for several functions to make a breakpoint on them. When we find and solve the bug, is there anyway to undebug()
all functions already marked by debug()
by a single command?
这里是一个很好的基准,可以看看您提出的方法是否真的完美:
Here is a good benchmark to see if your proposed method really works perfectly:
> library(limma) # bioconductor
> debug(read.ilmn)
> read.ilmn("a.txt") # No problem if this file does not exist
Browse[2]> debug(.read.oneilmnfile) # This is the debug browser for read.ilmn()
Browse[2]> Q # To exit debug browser
> undebug.all() # Here run your proposed function to undebug everything!
> read.ilmn("a.txt")
# Now if the debug browser is not started, you are lucky to pass this test!
您可能会在下面看到接受的答案。
You may see the accepted answer below. Any case for which this answer does not work, or cleaner versions, are more than welcome.
推荐答案
这是我的解决方案..
This was my solution ...
编辑:进行了修改,以处理在命名空间中查找对象。由于我不太真正了解操纵/查询名称空间的方法,并且由于我反复试验,因此代码已经变得有些繁琐。较干净的版本将受到欢迎。几乎肯定会有其他极端情况会失败。
edit: revised to deal with finding objects in namespaces. The code is already getting a little bit crufty, since I don't really understand the methods for manipulating/querying namespaces all that well, and since I was working by trial and error. Cleaner versions would be welcome. There are almost certainly other corner cases that will fail.
## return the names of the objects (from a vector of list of
## names of objects) that are functions and have debug flag set
isdebugged_safe <- function(x,ns=NULL) {
g <- if (is.null(ns)) get(x) else getFromNamespace(x,ns)
is.function(g) && isdebugged(g)
}
which_debugged <- function(objnames,ns=NULL) {
if (!length(objnames)) return(character(0))
objnames[sapply(objnames,isdebugged_safe,ns=ns)]
}
all_debugged <- function(where=search(), show_empty=FALSE) {
ss <- setNames(lapply(where,function(x) {
which_debugged(ls(x,all.names=TRUE))
}),gsub("package:","",where))
## find attached namespaces
## (is there a better way to test whether a
## namespace exists with a given name??)
ns <- unlist(sapply(gsub("package:","",where),
function(x) {
if (inherits({n <- try(getNamespace(x),silent=TRUE)},
"try-error")) NULL else x
}))
ss_ns <- setNames(lapply(ns,function(x) {
objects <- ls(getNamespace(x),all.names=TRUE)
which_debugged(objects,ns=x)
}),ns)
if (!show_empty) {
ss <- ss[sapply(ss,length)>0]
ss_ns <- ss_ns[sapply(ss_ns,length)>0]
}
## drop overlaps
for (i in names(ss))
ss_ns[[i]] <- setdiff(ss_ns[[i]],ss[[i]])
list(env=ss,ns=ss_ns)
}
undebug_all <- function(where=search()) {
aa <- all_debugged(where)
lapply(aa$env,undebug)
## now debug namespaces
invisible(mapply(function(ns,fun) {
undebug(getFromNamespace(fun,ns))
},names(aa$ns),aa$ns))
}
该代码也发布在
示例:
library(nlme)
debug(lme)
## define functions
source(url("http://www.math.mcmaster.ca/bolker/R/misc/undebug_all.R"))
undebug_all()
fm1 <- lme(distance ~ age, data = Orthodont) # from ?lme
在这种情况下 lme
无需进入调试器即可运行。
In this case lme
runs without entering the debugger.
另一个更难的示例:
library(limma)
source(url("http://www.math.mcmaster.ca/bolker/R/misc/undebug_all.R"))
debug(read.ilmn)
debug(limma:::.read.oneilmnfile)
all_debugged()
undebug_all()
read.ilmn()
read.ilmn("a.txt")
注意从调试的角度来看,$ c> read.ilmn()和 read.ilmn( a.txt)
的行为似乎有所不同(我不会不明白为什么...)
Note that read.ilmn()
and read.ilmn("a.txt")
appear to behave differently from a debugging standpoint (I don't understand why ...)
这篇关于调试所有功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!