R为会话结束定义(库)回调吗?

时间:2010-07-06 11:54:52

标签: r code-analysis

当我加载库(带有NAMESPACE)时,调用函数.onLoad.onAttach,当我分离卸载命名空间的库时调用.onUnload

我想知道R是否确定了一种方法,可以省去我在每个使用xxx库的脚本中手动分离/卸载库的工作。

为此我需要一个库钩子,当使用库的脚本结束时,如果有任何这样的事情,则会检查并调用它。我没有找到它,我总是想象有什么东西存在的原因以及为什么它们不存在。

我理解,从帮助文件和评论中,我可以使用.Last 脚本挂钩,但我正在寻找类似于构造函数/析构函数的东西:as一旦库“超出范围”(因为使用它的脚本结束),将调用“库析构函数”。


仍然换句话说,我想知道一个脚本真的只有两行吗?

#!/usr/bin/Rscript
library(xxx)

以及包含xxx和文件NAMESPACE的库zzz.R,其中包含其他内容

.onLoad <- function(libpath, pkgname) {
  packageStartupMessage("loading ", libpath, '::', pkgname)
}

.onUnload <- function(pkgpath) {
  packageStartupMessage("unloading ", pkgpath)
}

产生此输出

loading /usr/local/lib/R/site-library::xxx
unloading /usr/local/lib/R/site-library/xxx

或者如果我需要使用库detach('package:NenS', unload=TRUE)在每个脚本中显式调用xxx

1 个答案:

答案 0 :(得分:1)

这有点过时,但值得回答,因为它与代码覆盖相关,而R的代码覆盖工具是原始的。

如果您希望将某些内容组合在一起,可以使用foodweb()包中的mvbutils来确定脚本中哪些函数或调用依赖于给定包中的其他函数。

然后,程序可以在调用代码中查找最后一个依赖项,然后立即在正文中插入detach(...)

唯一的问题是代码不需要按字面顺序执行,如果函数的执行不明确,依赖关系可能会相当深或不透明(例如eval(parse(text = myCmd)) - {myCmd的值是多少1}}?它可以通过myCmd <- "library(myPackage)"设置。类似地,如果语句调用随后执行library(myPackage)的函数,则将再次加载您的包。但是,foodweb可以检测到这样的显式语句,这就是我寻找这种依赖的方式。

如果要对运行时数据进行分析,可以使用Rprof的输出,这将更好地了解是否使用了依赖项,但是将代码行匹配到调用堆栈目前面临挑战。尽管如此,您可以使用Rprof加上专门的回调来记录脚本中的进度,并尝试将代码行匹配到callstack,然后再依赖于依赖项。这里的问题是,这只是一次执行。

因此,简短的回答是,通过动态(运行时)分析可以看出,对于给定的运行,是否在给定的线路上使用了依赖关系,但是不能保证可以通过静态分析来实现