undebug all functions

前端 未结 3 1843
暗喜
暗喜 2021-02-03 22:27

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 fu

3条回答
  •  忘了有多久
    2021-02-03 23:02

    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))
    }
    

    The code is also posted at http://www.math.mcmaster.ca/bolker/R/misc/undebug_all.R

    Example:

    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
    

    In this case lme runs without entering the debugger.

    Another, harder example:

    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")
    

    Note that read.ilmn() and read.ilmn("a.txt") appear to behave differently from a debugging standpoint (I don't understand why ...)

提交回复
热议问题