roxygen2
roxygen2 copied to clipboard
Documenting R6 classes that are generated using function calls.
I would like to be able to document R6 classes that were generated by function calls.
One problem I encounter is that I am not sure how I can document methods when generating R6 classes this way.
E.g. in the example below, is it possible to document the method initialize
for the R6 class generator A
?
The problem is
library(R6)
r6_gen_gen = function(class, name) {
R6Class(class,
public = list(initialize = function(name) self$name = name, name = NULL)
)
}
A = r6_gen_gen("A", "Tom")
Created on 2022-10-19 by the reprex package (v2.0.1)
This is difficult, because roxygen needs an object of the class to be able to look up superclasses, methods, etc. So I am afraid that currently the only way to document your class is the manual way, i.e. manually create sections for methods, etc. inside the documentation of the r6_gen_gen()
function.
Why is it not possible to look up superclasses? The object A
is a standard R6ClassGenerator
, no?
It is for example possible to document the fields of A
. The problem I think is that in the documentation of the methods, there is no identifier what method is documented by the corresponding @description
block in the roxygen2 documentation itself so I presume roxygen looks at the source code and inspects the name of the function that follows each @description
block.
To make clearer what I mean: In the code below, the documentation of the field name
knows that it documents the field name
without looking at the source code, whereas the description of initialize
has to look at the source code, to know to which method it belongs.
A = R6::R6Class("A",
public = list(
#' @field name The name
name = NULL,
#' @description
#' Initializes an object.
initialize = function() print("Hallo!")
)
)
Created on 2022-10-19 by the reprex package (v2.0.1)
Maybe a solution would be to allow for a @method
so that the following would work:
r6_gen_gen = function(class, name) {
R6::R6Class(class,
public = list(initialize = function(name) self$name = name, name = NULL)
)
}
#' @title A
#' @description Blabla
#' @field name the name
#' @method initialize Creates a new object.
#' @export
A = r6_gen_gen("A", "Tom")
Created on 2022-10-19 by the reprex package (v2.0.1)
Right, if you actually create the A
object and put it in the package namespace, then we could look up the superclasses and also methods. I assumed that you don't want to put objects of the class into the package, since you want to avoid class objects in the package.
Alas, roxygen2 still cannot handle this currently, because it uses the source code of the class to match docs to methods.
Maybe your suggestion can be implemented, but I am not convinced that it is common that you have objects in a package, but not classes. So I don't think that we'll assign high priority to this.
But A
is a class, note that r6_gen_gen
generates a class and not an instance of the class.
The scenario in which this is useful is when one wants to create many classes that are very similar to one another but one still wants a different documentation for each class.
Like in the code below, I would like to generate documentation for the classes A
, B
, C
, ... (which all have a slightly different initialize method)
r6_gen_gen = function(class, x) {
R6::R6Class(class,
public = list(initialize = function() self$name = x, name = NULL)
)
}
#' @export
A = r6_gen_gen("A", "Tom")
#' @export
B = r6_gen_gen("B", "Lydia")
#' @export
C = r6_gen_gen("C", "Swathy")
...
Right, sorry, I understand it now.
I could have described it better as well! Thanks for taking the time :)
It would already help if there was the option to set r6 = TRUE
or r6 = FALSE
in a roxygen block and not only as one global option in the DESCRIPTION
You can do something like this:
#' @name myclass
#' ...
NULL
myclass <- r6_gen()
to avoid the R6 docs for myclass
.