Thanks for the quick answer. I didn't know about force() function. Cheers,
Henrik On Wed, Nov 23, 2011 at 6:56 PM, Simon Urbanek <simon.urba...@r-project.org> wrote: > IMHO this has nothing to do with capture.output() per se - it's simply lazy > evaluation that gets you. Add force(envir) before capture.output and it works > as you expected - the parent.frame() will be different inside capture.output > than outside. > > Cheers, > Simon > > > On Nov 23, 2011, at 9:36 PM, Henrik Bengtsson wrote: > >> I've noticed the following oddity where capture.output() prevents >> eval() from evaluating an expression in the specified environment. >> I'm not sure if it is an undocumented feature or a bug. It caused me >> many hours of troubleshooting. By posting it here, it might save >> someone else from doing the same exercise. >> >> Start by defining foo() which evaluates an expression locally in a >> given environment and catches the output via capture.output(): >> >> foo <- function(..., envir=parent.frame()) { >> capture.output({ >> eval(substitute({x <- 1}), envir=envir) >> }) >> } # foo() >> >> Then call: >> >>> suppressWarnings(rm(x)); foo(envir=globalenv()); print(x); >> character(0) >> [1] 1 >> >> This works as expected. However, if argument 'envir' is not specified >> explicitly, you get: >> >>> suppressWarnings(rm(x)); foo(); str(x); >> character(0) >> Error in str(x) : object 'x' not found >> >> which shows that the internal expression of foo() is *not* evaluated >> in the parent.frame(), i.e. the caller of foo(), which here should be >> globalenv(). It appears that capture.output() prevents this, because >> by dropping the latter: >> >> foo <- function(..., envir=parent.frame()) { >> eval(substitute({x <- 1}), envir=envir) >> } # foo() >> >> it works: >> >>> suppressWarnings(rm(x)); foo(); str(x); >> [1] 1 >> >> The workaround when still using capture.output() is to force an >> explicit evaluation of argument 'envir' inside of foo() before: >> >> foo <- function(..., envir=parent.frame()) { >> stopifnot(is.environment(envir)) # Workaround >> capture.output({ >> eval(substitute({x <- 1}), envir=envir) >> }) >> } # foo() >> >> which gives: >>> suppressWarnings(rm(x)); foo(); str(x); >> character(0) >> num 1 >> >> This occurs with R v2.14.0 patched and R devel: >> >>> sessionInfo() >> R version 2.14.0 Patched (2011-11-20 r57720) >> Platform: x86_64-pc-mingw32/x64 (64-bit) >> >> locale: >> [1] LC_COLLATE=English_United States.1252 >> [2] LC_CTYPE=English_United States.1252 >> [3] LC_MONETARY=English_United States.1252 >> [4] LC_NUMERIC=C >> [5] LC_TIME=English_United States.1252 >> >> attached base packages: >> [1] stats graphics grDevices utils datasets methods base >> >>> sessionInfo() >> R Under development (unstable) (2011-11-20 r57720) >> Platform: x86_64-pc-mingw32/x64 (64-bit) >> >> locale: >> [1] LC_COLLATE=English_United States.1252 >> [2] LC_CTYPE=English_United States.1252 >> [3] LC_MONETARY=English_United States.1252 >> [4] LC_NUMERIC=C >> [5] LC_TIME=English_United States.1252 >> >> attached base packages: >> [1] stats graphics grDevices utils datasets methods base >> >> /Henrik >> >> ______________________________________________ >> R-devel@r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel >> >> > > ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel