Debugging 列出在R中设置了调试标志的函数

Debugging 列出在R中设置了调试标志的函数,debugging,function,r,Debugging,Function,R,我试图在R中找到与isdebugged()相对应的全局函数。我的场景是,我有调用其他函数的函数,所有这些函数都是我编写的,我在调试期间为不同的函数打开和关闭debug()。但是,我可能会忘记哪些函数设置为调试。当我忘记并启动一个循环时,我可能会得到更多的输出(讨厌,但并不可怕),或者当需要一些输出时,我可能不会得到任何输出(糟糕) 我目前的方法是使用类似于下面的函数,我可以使用listDebugged(ls())调用它,或者在加载的库中列出项目(下面的示例)。这就足够了,但它要求我用工作区或加载

我试图在R中找到与
isdebugged()
相对应的全局函数。我的场景是,我有调用其他函数的函数,所有这些函数都是我编写的,我在调试期间为不同的函数打开和关闭
debug()
。但是,我可能会忘记哪些函数设置为调试。当我忘记并启动一个循环时,我可能会得到更多的输出(讨厌,但并不可怕),或者当需要一些输出时,我可能不会得到任何输出(糟糕)

我目前的方法是使用类似于下面的函数,我可以使用
listDebugged(ls())
调用它,或者在加载的库中列出项目(下面的示例)。这就足够了,但它要求我用工作区或加载的包中的每个函数的列表来调用它。我可以包装另一个函数来获得这些。似乎应该有一种更简单的方法可以直接“询问”调试函数,或者查询环境中某个模糊的部分,在该部分中,它存储了设置了调试标志的函数列表

因此,问题分为两部分:

  • 是否存在一个更简单的调用来查询设置了调试标志的函数
  • 如果没有,那我有没有忽略了什么诡计?例如,如果一个包中的函数屏蔽了另一个,我怀疑我可能会返回一个误导性的结果
  • 我意识到我可以尝试另一种方法,那就是在函数中包装
    debug
    undebug
    ,这些函数还维护一个隐藏的已调试函数名列表。我还不认为这样做是安全的

    更新(8/5/11):我搜索了这么多,没有找到以前的问题。然而,SO的“相关问题”列表显示,尽管该问题答案中的函数比@cbeleites提供的函数更详细、更慢。以前的问题也没有提供任何代码,而我提供了。:)

    守则:

    listDebugged    <- function(items){
        isFunction  <- vector(length = length(items))
        isDebugged  <- vector(length = length(items))
    
        for(ix in seq_along(items)){
            isFunction[ix]  <- is.function(eval(parse(text = items[ix])))
        }
    
        for(ix in which(isFunction == 1)){
            isDebugged[ix]  <- isdebugged(eval(parse(text = items[ix])))
        }
        names(isDebugged)   <- items
        return(isDebugged)
    }
    
    # Example usage
    listDebugged(ls())
    library(MASS)
    debug(write.matrix)
    listDebugged(ls("package:MASS"))
    

    listDebugged下面是我对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)
    }
    

    ls.deb从最初的问题开始,我越来越关注它。如果使用该软件包,则
    check.for.traces()
    是列出通过
    mtrace
    调试的函数的适当命令


    如果你花很多时间使用R调试器和各种
    跟踪
    选项,那么调试包值得一看。

    @cbeleites我喜欢你的答案,但它对我不起作用。我得到了这个工作,但它没有你上面的功能(没有递归检查,没有漂亮的打印)

    require(plyr)
    
    debug.ls我经常被困在
    浏览器
    窗口框架中,因为无法解除bug功能。因此,我创建了两个函数,并将它们添加到我的
    .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())
      }
    }
    
    require(日志记录)
    #返回设置调试标志的函数向量
    
    debuggedFuns这是一个简单的单行程序,使用
    lsf.str

    which(sapply(lsf.str(), isdebugged))
    

    您可以更改函数内的环境,有关更多参数,请参见
    ?lsf.str

    在R base中,除了包装
    调试
    函数外,没有其他方法可以完成此工作。+1这很好,似乎可以。我现在正在逐步了解它,了解它使用
    f
    做什么。聪明。我的疏忽:使用
    debug()
    单步执行是了解它在做什么的更好方法。最佳使用
    debug
    。)谢谢我从这个函数中学到了一些新的函数和想法。一个检查所有附加函数的例子:
    名称(它(sapply(unlist(lappy(search(),function(x)lsf.str(pos=x))),isdebuged))
    @sedsiv请在你的答案中添加注释。你的不适合我。
    which(sapply(lsf.str(), isdebugged))