does R define a (library) callback for session end?
when I load a library (with a NAMESPACE
), the functions .onLoad
and .onAttach
are called, as is .onUnload
when I detach the library unloading the namespace.
I was wondering whether R does define a way that would save me the work of detaching/unloading the library by hand in each of my scripts that use the xxx
library.
for this I would need a library hook that is checked and invoked when a script using the library ends, if there is any such thing. I didn't find it, and I always imagine there is a reason why things are there as well as why they are not.
I understand, from the help files and from the comments, that there is a .Last
script hook I can use, but I am looking for something similar to constructor/destructor: as开发者_如何学Go soon as the library "goes out of scope" (because the script using it ends), the "library destructor" would be invoked.
still in other words, I am wondering whether it is at all possible that a script with really only the two lines
#!/usr/bin/Rscript
library(xxx)
and a library xxx
with a NAMESPACE
and a file zzz.R
containing among other stuff this
.onLoad <- function(libpath, pkgname) {
packageStartupMessage("loading ", libpath, '::', pkgname)
}
.onUnload <- function(pkgpath) {
packageStartupMessage("unloading ", pkgpath)
}
produces this output
loading /usr/local/lib/R/site-library::xxx
unloading /usr/local/lib/R/site-library/xxx
or if I need to explicitly call detach('package:NenS', unload=TRUE)
in each script using the library xxx
.
This is a little dated, but worth answering, since it is relevant to code coverage, and R's tools for code coverage are primitive.
If you desire to rig something together, you could use foodweb()
in the mvbutils
package to identify which functions or calls in your script depend on other functions from a given package.
A program could then look for the last dependency in the calling code and insert a detach(...)
in the body immediately afterward.
The only issue is that code need not be executed in literally sequential order, and dependencies could be rather deep or opaque if execution of a function isn't explicit (e.g. eval(parse(text = myCmd))
- what is the value of myCmd
? It could've been set via myCmd <- "library(myPackage)"
). Similarly, if a statement invokes a function that subsequently executes library(myPackage)
, your package will be loaded again. However, foodweb
can detect such explicit statements, which is how I have looked for such dependencies.
If you want to do analysis of runtime data, you could use the output of Rprof
, which will be a much better insight into whether or not a dependency was used, but matching lines of code to the call stack is currently challenging. Nonetheless, you could use Rprof
plus a specialized callback to record progress in the script and try to match lines of code to the callstack, and then to dependencies. The problem here is that that is just one execution.
So, the short answer is that it is possible through dynamic (runtime) analysis to see if, for a given run, a dependency was utilized at a given line, but it is not guaranteed that one could do so from static analysis.
精彩评论