- Update on 2020-06-23
-
The issue mentioned in this post has been fixed in R 4.0.2, thanks to Martin Maechler.
I have used on.exit()
for several years, but it was not until the other day that I realized a very weird thing about it: you’d better follow the default positions of its arguments expr
and add
, i.e., the first argument has to be expr
and the second has to be add
.
on.exit(expr = NULL, add = FALSE)
If you do on.exit(add = TRUE, {...})
, weird things can happen. I discovered this by accident. I have never switched the positions of expr
and add
before, and I was surprised that R CMD check
failed on Travis with an error message that confused me in the beginning:
Error in on.exit(add = TRUE, if (file.exists(main)) { :
invalid 'add' argument
I was thinking why add = TRUE
was considered invalid. Then I guessed perhaps the expression if (file.exists(main)) {}
was treated as the actual value of add
. So I switched to the normal order of arguments, and the error was gone.
I tested it a bit more and was totally confused, e.g., why was 1
printed twice below? I guess TRUE
was not printed because add
was treated as expr
.
f = function() {
on.exit(add = print(TRUE), print(1))
}
f()
# [1] 1
# [1] 1
I don’t have the capability to understand the source code in C, and I’ll leave it experts to explain the weird things I observed. For me, I’ll just never move add
before expr
again.
BTW, I don’t know the rationale for the default add = FALSE
in on.exit()
, but I have not used add = FALSE
for a single time, so I feel add = TRUE
might be a better default. When I want to do something on exit, I almost surely mean do it in addition to the things that I assigned to on.exit()
before, instead of cleaning up all previous tasks and only doing this one (add = FALSE
).
- Update on 2018-01-17
-
Half a year later, I was bitten by the same problem again in the tinytex package. Never, ever, do
on.exit(add = TRUE, expr)
.