on.exit() & sys.on.exit(): Calling them via eval() does not work as hoped
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