[Rd] on.exit() & sys.on.exit(): Calling them via eval() does not work as hoped
Henrik Bengtsson
hb at biostat.ucsf.edu
Sun Nov 3 22:19:37 CET 2013
On Sun, Nov 3, 2013 at 2:16 AM, Peter Meilstrup
<peter.meilstrup at gmail.com> wrote:
> 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.
Brilliant wording :)
> 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())
> }
Interesting, but also worrying at the same time. Since these are
undocumented(*) "features" of on.exit()/sys.on.exit() and it works for
on.exit() and not sys.on.exit(), it also means that I'm not sure if I
can rely on this do.call() workaround to not break in the future. If
would be great to hear what the R core team thinks about this.
(*) There is a small note in help("on.exit") saying "This is a
‘special’ primitive function: it only evaluates the argument add.".
/Henrik
>
> 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
More information about the R-devel
mailing list