这是我的解决方案...
编辑:修改以处理在命名空间中查找对象。代码已经变得有点笨拙了,因为我不太了解操作/查询命名空间的方法,而且我一直在反复试验。更清洁的版本将受到欢迎。几乎可以肯定还有其他极端情况会失败。
## 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))
}
该代码也发布在http://www.math.mcmaster.ca/bolker/R/misc/undebug_all.R
例子:
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
,无需进入调试器即可运行。
另一个更难的例子:
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")
请注意,从调试的角度来看read.ilmn()
,read.ilmn("a.txt")
它的行为似乎有所不同(我不明白为什么......)