From peter.meilstrup at gmail.com  Sun Nov  3 11:16:45 2013
From: peter.meilstrup at gmail.com (Peter Meilstrup)
Date: Sun, 3 Nov 2013 02:16:45 -0800
Subject: [Rd] on.exit() & sys.on.exit(): Calling them via eval() does
 not work as hoped
In-Reply-To: <CAFDcVCTsGqADPyf_MAiNmLKZofLpy-BkXGABXT6G5=kjotMQcw@mail.gmail.com>
References: <CAFDcVCTsGqADPyf_MAiNmLKZofLpy-BkXGABXT6G5=kjotMQcw@mail.gmail.com>
Message-ID: <CAJoaRhbVstp3U_fxUH09dPFeSvuM3DU0otROWYnrYxpqwEpk-g@mail.gmail.com>

eval() tends to be able to convince normal functions of where they are
executing, but primitive functions use different methods to get their
evaluation context and aren't as easily fooled. It turns out do.call()
works better on primitive functions, and it will work for "on.exit".
However I wasn't able to get 'sys.on.exit' to work.

add_on_exit <- function(what) {
  do.call("on.exit", list(substitute(what), add=TRUE), envir=parent.frame())
}

bar <- function() {
  on.exit(print("exit 1"))
  eval(quote(on.exit(print("exit 2"), add=TRUE))) #nope
  do.call("on.exit", alist(print("exit 3"), add=TRUE))
  add_on_exit(print("exit 4"))
  cat("sys.on.exit():\n")
  x <- sys.on.exit()
  print(x)
  cat("----- exiting\n")
}

> bar()
[1] "exit 2"
sys.on.exit():
{
    print("exit 1")
    print("exit 3")
    print("exit 4")
}
----- exiting
[1] "exit 1"
[1] "exit 3"
[1] "exit 4"


On Sat, Nov 2, 2013 at 9:24 PM, Henrik Bengtsson <hb at biostat.ucsf.edu> wrote:
> Why does the following eval() call on sys.on.exit() not return what I
> expect/evaluate in the proper environment?
>
> foo <- function() {
>   cat("foo()...\n");
>   on.exit( message("exiting") )
>
>   cat("sys.on.exit():\n")
>   res <- sys.on.exit()
>   print(res)
>
>   cat("eval(sys.on.exit()):\n")
>   expr <- quote(sys.on.exit())
>   print(expr)
>   res <- eval(expr)
>   print(res)
>
>   cat("foo()...done\n")
> }
>
>> foo()
> foo()...
> sys.on.exit():
> message("exiting")
> eval(sys.on.exit()):
> sys.on.exit()
> NULL
> foo()...done
> exiting
>
> Similar problems appear when I try to "record" on.exit() expressions
> via eval().  It appears that the "primitives" on.exit() and
> sys.on.exit() do something rather special.  Is there a solution to
> what I'm trying to do?
>
> The reason why I'm doing this in the first place, is that I'm trying
> to implement onExit(<expr>, where="replace"), onExit(<expr>,
> where="last"), and onExit(<expr>, where="first").
>
> Thanks,
>
> Henrik
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] on.exit() & sys.on.exit(): Calling them via eval() does not work as hoped
Peter Meilstrup