[Rd] Exiting R and package detachment?

Prof Brian Ripley ripley at stats.ox.ac.uk
Fri Jun 10 14:44:06 CEST 2005


On Fri, 10 Jun 2005, Henrik Bengtsson wrote:

> Prof Brian Ripley wrote:
>> Note that you can terminate R via q() without running .Last, and indeed how 
>> R is terminated is up to the front-end in use.  So the answer to
>> 
>>> is there away to assure that a package is detached when R quits?
>> 
>> 
>> is `No'.
>
> Thank you for this. After rereading the ?Last, I wonder, is it 
> .Internal(quit(...)) that calls .Last() or is it some other lower-level 
> mechanism that does this?  In other words, is it only when quit(runLast=TRUE) 
> is called that .Last() is called?

It is done by the front-end's termination code, e.g. RStd_CleanUp on 
terminal-based Unix.

>
> /Henrik
>
> PS. I know the answer is in the source code, but I'm behind a 56k modem 
> without having the source code on my laptop. DS.

Look at Writing R Extensions, which does explain all this.

>> On Fri, 10 Jun 2005, Henrik Bengtsson wrote:
>> 
>>> Hi,
>>> 
>>> is there away to assure that a package is detached when R quits?  I know
>>> about .Last(), but that requires the user to setup that function.  What
>>> I am looking for is a way for the package to do this itself, without
>>> asking the user to edit "their" .Last().  From ?setHook I know that:
>>> 
>>>   "...when an R is finished, packages are not detached and namespaces
>>> are not unloaded, so the corresponding hooks will not be run."
>>> 
>>> I am going to use this to load settings from file when a package loads
>>> and automatically save (by optionally prompting the user) them back to
>>> file when the package is no longer available (==detached/unloaded/R
>>> quits).  I am currently loading the settings in .First.lib() and have
>>> code in .Last.lib() to save them.
>>> 
>>> Are there other ways to assure functions to be called when R quits?  The
>>> best I can think of now is to "hack" .Last() by doing something like
>>> 
>>> if (!exists(".LastOriginal", mode="function")) {
>>>   .LastOriginal <<- get(".Last", envir=.GlobalEnv);
>>> 
>>>   .Last <<- function(..., envir=parent.frame()) {
>>>     for (fun in getHook(".Last")) {
>>>       if (is.character(fun))
>>>         fun <- get(fun, mode="function")
>>>       try(fun());
>>>     }
>>>     eval(.LastOriginal(...), envir=envir);
>>>   } # .Last()
>>> }
>>> 
>>> Then in package <pkg>:
>>> .First.lib <- function(libname, pkgname) {
>>>   # Detach package when R finishes.
>>>   setHook(".Last", function(...) {
>>>     pos <- match(paste("package:", pkgname, sep=""), search());
>>>     if (!is.na(pos))
>>>       detach(pos=pos);
>>>   })
>>> }
>>> 
>>> However, this will be broken if user redefines .Last().  What about
>>> defining a hook "onSessionExit" to be called before (after?) .Last() is
>>> called.  In analogue to on.exit() one could then define
>>> 
>>> onSessionExit <- function(fcn, ...) {
>>>   setHook("onSessionExit", fcn, ...);
>>> }
>>> 
>>> 
>>> Just curious, the above quote makes me wonder what is the rational for
>>> the behavior?  Was it made on purpose or is it simply just easier for R
>>> to finish without detaching/unloading packages first?  In what
>>> situations to you have "clean-up" code for a package that is only called
>>> when detach("package:<pkg>") is used?  One situation I can imaging is
>>> when a bundle of packages are loaded and when you detach the package
>>> that all other packages requires, the other packages are also detached
>>> for conveniency.
>>> 
>>> Best wishes
>>> 
>>> Henrik
>>> 
>>> ______________________________________________
>>> R-devel at r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>> 
>>> 
>> 
>
>

-- 
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595



More information about the R-devel mailing list