4

我目前正在改进对其他脚本有不同调用的代码,我想知道对象是在哪里创建的。对于其中一些人来说,只需使用文本编辑器的搜索选项即可。只看是否obj <-obj =有任何结果。但这不适用于使用该assign函数创建的那些。在加载的脚本中创建的也不是。

发生错误时的debug()函数会告诉它发生的位置,即使它在另一个脚本中。但是有什么函数可以告诉代码行它是创建一个对象吗?有没有其他工具?

也许grepl可以做到,但我不知道如何创建这样的功能......

4

1 回答 1

5

听起来您基本上想要一个函数来识别何时使用调试器创建新对象。您可以做的最简单的事情就是ls(envir=.GlobalEnv)在浏览器中输入以查看您拥有的对象。或者,您可以编写一个函数,仅向您显示自上次查看以来的新对象(即,创建了哪些新对象(例如,在全局环境中)。这是一个执行此操作的函数:

comparels <- function(){
    oldls <- try(get('oldls', envir=.GlobalEnv))
    if(inherits(oldls, 'try-error'))
        oldls <- list()
    newls <- ls(.GlobalEnv)
    assign('oldls',newls, envir=.GlobalEnv)
    gone <- oldls[!oldls %in% newls]
    added <- newls[!newls %in% oldls]
    list(gone=gone, added=added)
}

这是它向您展示的示例:

> comparels()
$gone
list()

$added
[1] "comparels"

> a <- 1
> b <- 2
> c <- 3
> comparels()
$gone
character(0)

$added
[1] "a"     "b"     "c"     "oldls"

然后,如果您在函数的调试器上运行它(下面是一个简单的示例),您将能够调用comparels()并查看在函数的任何给定点创建了哪些新对象:

funtodebug <- function(){
  for(i in 1:100){
    assign(paste('obj',i,sep='_'), i, .GlobalEnv)
  }
}
debug(funtodebug)

> funtodebug()
debugging in: funtodebug()
debug at #1: {
    for (i in 1:100) {
        assign(paste("obj", i, sep = "_"), i, .GlobalEnv)
    }
}
Browse[2]> 
debug at #2: for (i in 1:100) {
    assign(paste("obj", i, sep = "_"), i, .GlobalEnv)
}
Browse[2]> 
debug at #2: i
Browse[2]> 
debug at #3: assign(paste("obj", i, sep = "_"), i, .GlobalEnv)
Browse[2]> 
debug at #2: i
Browse[2]> 
debug at #3: assign(paste("obj", i, sep = "_"), i, .GlobalEnv)
Browse[2]> comparels()
$gone
character(0)

$added
[1] "funtodebug" "obj_1" 

编辑: 另一种方法是使用任务回调comparels在顶层发生任何事情时调用该函数,从而在创建新对象时打印。这是一个简单的例子:

addTaskCallback(function(expr,value,ok,visible) {
    print(comparels())
    TRUE},
    name='ls')

a <- 1
b <- 2
a
b
3+3

# remove the callback
removeTaskCallback('ls') 

这使您不必调试整个程序。您可以在运行代码之前简单地触发回调,然后查看会发生什么,然后删除回调。

于 2013-11-22T09:18:11.723 回答