org - R undebug todas las funciones
r repository (3)
Aquí hay una opción, asumiendo que las funciones que está depurando están en el área de trabajo o el entorno global. Se puede especificar cualquier entorno particular para que sea adaptable, pero esto no va a ser algo que funcione para cualquier función en todos los paquetes cargados de una sola vez.
Primero ilustre a través de un par de funciones en el entorno global:
> bar <- function() {}
> foo <- function() {}
Use lsf.str()
para devolver las funciones en el área de trabajo (para su uso posterior, unclass()
y convertiremos esto en una lista):
> funlist <- as.list(unclass(lsf.str()))
> funlist
[[1]]
[1] "bar"
[[2]]
[1] "foo"
A continuación, genere un indicador para estas funciones en cuanto a si están depuradas:
> debugged <- sapply(funlist, isdebugged)
> debugged
[1] FALSE FALSE
OK, entonces debug()
una de las funciones y vuelve a ejecutar:
> debug(bar)
>
> debugged <- sapply(funlist, isdebugged)
> debugged
[1] TRUE FALSE
Finalmente, sapply()
sobre funciones funlist
que se depuran aplicándoles undebug()
:
> sapply(funlist[debugged], undebug)
[[1]]
NULL
Esto, por supuesto, podría ser encapsulado en una función
undebugFuns <- function() {
funs <- unclass(lsf.str())
dbg <- sapply(funs, isdebugged)
if(isTRUE(any(dbg))) {
writeLines(paste("Un-debugging:", funs[dbg]))
sapply(funs[dbg], undebug)
} else {
writeLines(paste("Nothing to debug"))
}
invisible()
}
> debug(bar)
> undebugFuns()
Un-debugging: bar
Un tipo de depuración no recogido por isdebugged()
es el que se promulga a través de debugonce()
:
> debug(bar)
> isdebugged(bar)
[1] TRUE
> undebugFuns()
Un-debugging: bar
> debugonce(bar)
> isdebugged(bar)
[1] FALSE
Lo que solo sirve para hacer que el punto de Josh en su Respuesta sea nuevamente.
Considere que hemos llamado a debug()
para varias funciones para hacer un punto de interrupción en ellas. Cuando encontramos y resolvemos el error, ¿hay de todos modos undebug()
todas las funciones ya marcadas por debug()
con un solo comando?
Aquí hay un buen punto de referencia para ver si su método propuesto realmente funciona perfecto:
> 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!
Puede ver la respuesta aceptada a continuación. Cualquier caso que esta respuesta no funcione, o versiones más limpias son más que bienvenidos.
Esta fue mi solución ...
edición : revisada para tratar de encontrar objetos en los espacios de nombres. El código ya se está volviendo un poco complicado, ya que no entiendo bien los métodos para manipular / consultar espacios de nombres tan bien, y ya que estaba trabajando por prueba y error. Las versiones más limpias serían bienvenidas. Es casi seguro que hay otros casos de esquina que fallarán.
## 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))
}
El código también se publica en http://www.math.mcmaster.ca/bolker/R/misc/undebug_all.R
Ejemplo:
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
En este caso, lme
ejecuta sin entrar en el depurador.
Otro ejemplo más difícil:
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")
Tenga en cuenta que read.ilmn()
y read.ilmn("a.txt")
parecen comportarse de manera diferente desde el punto de vista de la depuración (no entiendo por qué ...)
No, no hay una forma completamente confiable de undebug()
todas las funciones undebug()
. (Solo digo esto porque lo he visto discutido varias veces en R-devel y R-help).
En esta discusión , Brian Ripley intervino, señalando que:
La depuración es una propiedad de un objeto de función (un bit en el sxpinfo) y, por lo tanto, tendría que atravesar todos los objetos accesibles (como hace gc) para encontrarlos todos.
Aquí hay un fragmento en el que Robert Gentleman responde (en negativo) una pregunta sobre si "hay una forma conveniente de saber en cualquier momento cuáles son las funciones marcadas con debug()
o trace()
en una sesión R":
Probablemente no recibiste una respuesta porque la respuesta es no, no hay una manera fácil.