如何找到对象的创建位置?

时间:2013-11-06 15:24:10

标签: r

我目前正在努力改进对其他脚本有不同调用的代码,我想知道对象的创建位置。 对于其中一些只使用文本编辑器的搜索选项工作。只需查看obj <-obj =是否有任何结果。但这不适用于使用assign函数创建的内容。也就是在加载的脚本中创建的那些。

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

也许用grepl它可以完成,但我不知道创建这样的函数......

1 个答案:

答案 0 :(得分: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') 

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