[R] on.exit() inside local()

Gabor Grothendieck ggrothendieck at myway.com
Tue Aug 10 08:05:40 CEST 2004


Vadim Ogranovich <vograno <at> evafunds.com> writes:

: 
: Hi,
: 
: Since I routinely open files in a loop I've developed a habit of using
: on.exit() to close them. Since on.exit() needs to be called within a
: function I use eval() as a surrogate. For example:
: 
: for (fileName in c("a", "b")) eval({
: 	con <- file(fileName);
: 	on.exit(close(con))
: 	}) 
: 
: and con will be closed no matter what.
: 
: However it stopped working once I wrapped the loop in local():
: > local(
: +       for (foo in seq(2)) eval({
: +         on.exit(cat(foo, "\n"))
: +       })
: + )
: Error in cat(foo, "\n") : Object "foo" not found
: 
: 
: W/o local()it works just fine
: >       for (foo in seq(2)) eval({
: +         on.exit(cat(foo, "\n"))
: +       })
: 1 
: 2 
: 
: The reason I wanted the local() is to keep 'foo' from interfering with
: the existing environments, but somehow this breaks the thing.
: At this point I am stuck. Could someone please tell what's going on?

The on.exit code is executing in an environment whose parent is
namespace:base and so cannot access the environment created by
local.  Use evalq, instead of eval, which has the effect of
running the on.exit code in the environment created by
local:

local({
   for (i in c("a", "b")) evalq(
         on.exit(cat(i, "\n"))
      )
})

or use an inner local, which has the effect of creating
a new environment for each iteration of the loop in which
the on.exit code runs:

local({
   for (i in c("a", "b")) local(
      on.exit(cat(i, "\n"))
   )
})




More information about the R-help mailing list