roxygen2
roxygen2 copied to clipboard
Cleaning up state after execution of chunks
These would be run after all the chunks of an Rd file have rendered.
Not sure what would be a good workflow:
```{r, include = FALSE}
old <- getOption("foo")
```
```{r}
options(foo = "bar")
```
```{r, include = FALSE}
rd_defer(options(old))
```
Alternatively maybe knitr should be run in a separate process, one per Rd file. Then no clean up is needed. If that is feasible, I think that'd be the preferred solution.
In that case the evaluation environment should be set back to the global env rather than a child. This would solve some current issues about finding S3 methods for instance.
I think if the options are set temporarily in #1091 then that takes care of the cleanup as well, no? I.e. if you want an option for all Rmds you put it in DESCRIPTION. If you want it for a single Rmd, then you can use knitr's chunk options to set them:
R.options: (NULL) local R options for a code chunk; these options are set temporarily via options() before the code chunk, and restored after the chunk
There's much more state than options to clean up.
if you want an option for all Rmds you put it in DESCRIPTION
What do you mean by DESCRIPTION? I think we'd want to set and clean up options (and other state) per .Rd file rather than per package.
There's much more state than options to clean up.
I know, but knitr does not do that in general, and I am not sure if it is our job to fix it here. If you are worried about that, then run R -q -e 'devtools::document()' from a shell, maybe? The RStudio IDE also runs document() in a separate process.
What do you mean by DESCRIPTION? I think we'd want to set and clean up options (and other state) per .Rd file rather than per package.
I think it makes sense to have some of them package-wide, e.g. width.
I run document in a separate process, but my concern is with interactions between .Rd files. This problem will come up more as we switch to this method documentation.
It would be great if knitr gained tools for clean up, but I think it'd be better to evaluate in global and just not worry about stuff left there for example. Also I would like to attach packages without influencing other .Rd files.
It seems that knitting all chunks of a given .Rd file in a separate process is the right thing to do in principle.
To be precise, the chunks of a single .Rd file should be evaluated in the same external process.
That's not how roxygen works, though. A single roxygen tag might generate text for several Rd files, e.g. via the @inherit mechanism. That means that you cannot define options per Rd file. We could set options for the whole document() run, we could set options for a single roxygen block, and you can probably already define your options for a single Rmd, using the R.options knitr chunk option.
Ah makes sense. Then maybe the reasoning above should be for individual sections, description and details? I don't think state-cleaning is important for things like @params.
Sorry this is my fault for using the options example in the first post, but really this is about attaching packages, or assigning stuff like S3 methods in the global env.
Sorry this is my fault for using the options example in the first post, but really this is about attaching packages, or assigning stuff like S3 methods in the global env.
In this case we need an external process. And yeah, it would be best to have one per Rd file, but that is probably for roxygen3. But we could do one per block. The current evaluator uses one env per block, so optionally you could have one process per block?
We would only do it for blocks that actually have evaluated code.
By block you mean something like an Rd section right? So multiple chunks inside a section would be evaluated in the same process?
A block is a continuous subset of #' lines, ignoring empty lines and regular comment lines.
What delineates the continuous subsets?
Related problem, setting knitr options in a chunk doesn't affect the other chunks.
What delineates the continuous subsets?
I am probably not explaining this right. It is like this:
roxy-block
R-code
roxy-block
R-code
...
roxy_block may contain empty lines or regular, non-roxy comment lines.
Related problem, setting knitr hooks in a chunk doesn't affect the other chunks.
Can you have a reprex in another issue? Thanks.
We can discuss having a sub-process for clean state, but I think this would be opt in. I agree completely that a clean state would be nice, but starting up a process takes 200-400ms and that does not include loading the packages, so I afraid that we cannot make it the default.