-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Documenting R6 classes with and without roxygen2 #3
Comments
Well, I guess eventually roxygen2 will support R6. It has already has some methods to parse docstrings from reference classes, these can be handy to do the same for R6 classes. For now the only option is to write the man page(s) by hand. You can close this for now if you want, or just leave it here as a reminder. I'll also open an issue |
Hi thanks |
I have managed a workaround to be able to use ROXygen for the documentation of a package using R6 classes. I have a doc_myClass.R in the R folder with a RC class with a prototype (fields and empty methods) mimicking the real R6 Class and its public methods, only for documentation sake:
Each RC method must contain a docstring that will be used by ROxygen2 for the class documentation. The class is named xyz or whatever else you want, but not the R6 class name you will really export. Then, open the generated "xyz-class.Rd" text file and replace xyz with your real R6 class name; do the same with the file name. Now convert the ROxygen comments in your 'xyz' class to normal comments to avoid the generation of documentation for the fake xyz class. I know this is ugly, but it is just for the class documentation as whole. For the documentation of your R6 Class methods. I am using the following schema: Create a (temporal) list and add to it functions with the signature of your real R6 class public methods and document it with regular ROxygen2. Use the This way, when the final user executes Unfortunately if the user runs
@wch: It seems like R is interacting with your R6 class generator trying to handle the '$' function in the search for the corresponding help text. Is it possible to add some feature to the R6ClassGenerator in order to avoid this error?
|
thanks for the workaround |
I really like R6 classes. I have found that using something like
works well. Specifying
Just a pity that R CMD check will not warn if the method arguments are not properly documented. |
@jranke This is actually quite good, although I haven't looked at the output yet. Btw. is |
@gaborcsardi Yes, you are right. I removed it from my comment above - maybe my approach is a bit experimental. But it produces nice Rd output and the generator objects get exported. Just didn't publish the package yet where I am using this approach. |
I think this is a useful placeholder, but can I suggest future discussion happen over at r-lib/roxygen2#306 ? |
For those stumbling here looking for a way / example to document their R6 class, I found this to be a nice template: #' Class providing object with methods for communication with lightning-viz server
#'
#' @docType class
#' @importFrom R6 R6Class
#' @importFrom RCurl postForm
#' @importFrom RJSONIO fromJSON toJSON
#' @importFrom httr POST
#' @export
#' @keywords data
#' @return Object of \code{\link{R6Class}} with methods for communication with lightning-viz server.
#' @format \code{\link{R6Class}} object.
#' @examples
#' Lightning$new("http://localhost:3000/")
#' Lightning$new("http://your-lightning.herokuapp.com/")
#' @field serveraddress Stores address of your lightning server.
#' @field sessionid Stores id of your current session on the server.
#' @field url Stores url of the last visualization created by this object.
#' @field autoopen Checks if the server is automatically opening the visualizations.
#' @field notebook Checks if the server is in the jupyter notebook mode.
#' #' @section Methods:
#' \describe{
#' \item{Documentation}{For full documentation of each method go to https://github.com/lightning-viz/lightining-r/}
#' \item{\code{new(serveraddress)}}{This method is used to create object of this class with \code{serveraddress} as address of the server object is connecting to.}
#'
#' \item{\code{sethost(serveraddress)}}{This method changes server that you are contacting with to \code{serveraddress}.}
#' \item{\code{createsession(sessionname = "")}}{This method creates new session on the server with optionally given name in \code{sessionname}.}
#' \item{\code{usesession(sessionid)}}{This method changes currently used session on the server to the one with id given in \code{sessionid} parameter.}
#' \item{\code{openviz(vizid = NA)}}{This method by default opens most recently created by this object visualization. If \code{vizid} parameter is given, it opens a visualization with given id instead.}
#' \item{\code{enableautoopening()}}{This method enables auto opening of every visualisation that you create since that moment. Disabled by default.}
#' \item{\code{disableautoopening()}}{This method disables auto opening of every visualisation that you create since that moment. Disabled by default.}
#' \item{\code{line(series, index = NA, color = NA, label = NA, size = NA, xaxis = NA, yaxis = NA, logScaleX = "false", logScaleY = "false")}}{This method creates a line visualization for vector/matrix with each row representing a line, given in \code{series}.}
#' \item{\code{scatter(x, y, color = NA, label = NA, size = NA, alpha = NA, xaxis = NA, yaxis = NA)}}{This method creates a scatterplot for points with coordinates given in vectors \code{x, y}.}
#' \item{\code{linestacked(series, color = NA, label = NA, size = NA)}}{This method creates a plot of multiple lines given in matrix \code{series}, with an ability to hide and show every one of them.}
#' \item{\code{force(matrix, color = NA, label = NA, size = NA)}}{This method creates a force plot for matrix given in \code{matrix}.}
#' \item{\code{graph(x, y, matrix, color = NA, label = NA, size = NA)}}{This method creates a graph of points with coordinates given in \code{x, y} vectors, with connection given in \code{matrix} connectivity matrix.}
#' \item{\code{map(regions, weights, colormap)}}{This method creates a world (or USA) map, marking regions given as a vector of abbreviations (3-char for countries, 2-char for states) in \code{regions} with weights given in \code{weights} vector and with \code{colormap} color (string from colorbrewer).}
#' \item{\code{graphbundled(x, y, matrix, color = NA, label = NA, size = NA)}}{This method creates a bundled graph of points with coordinates given in \code{x, y} vectors, with connection given in \code{matrix} connectivity matrix. Lines on this graph are stacked a bit more than in the \code{graph} function.}
#' \item{\code{matrix(matrix, colormap)}}{This method creates a visualization of matrix given in \code{matrix} parameter, with its contents used as weights for the colormap given in \code{colormap} (string from colorbrewer).}
#' \item{\code{adjacency(matrix, label = NA)}}{This method creates a visualization for adjacency matrix given in \code{matrix} parameter.}
#' \item{\code{scatterline(x, y, t, color = NA, label = NA, size = NA)}}{This method creates a scatterplot for coordinates in vectors \code{x, y} and assignes a line plot to every point on that plot. Each line is given as a row in \code{t} matrix.}
#' \item{\code{scatter3(x, y, z, color = NA, label = NA, size = NA, alpha = NA)}}{This method creates a 3D scatterplot for coordinates given in vectors \code{x, y, z}.}
#' \item{\code{image(imgpath)}}{This method uploads image from file \code{imgpath} to the server and creates a visualisation of it.}
#' \item{\code{gallery(imgpathvector)}}{This method uploads images from vector of file paths \code{imgpathvector} to the server and creates a gallery of these images.}}
Lightning <- R6Class("Lightning",
...
) |
Thanks @petermeissner ! I was "stumbling here looking for a way / example to document their R6 class" 😄 |
I have some documented R6 classes in storr - Rd here and rendered here. I think this is actually quite a hard thing to get right in general, but definitely doable for someone sufficiently motivated. |
Thanks @richfitz 👍 For now I have no methods to document, only slots, because even initializing happens in a non-exported function so that's easy but I can see it getting more complicated later! |
thanks for providing the documentation example. The .Rd says that it was created using roxygen from R/storr.R, but looking at the storr.R code, I couldn't find the documentation there that lets one create this. Is there some trick to it? Thanks! |
Yes, sorry, there is a trick (not one I'd recommend - native roxygen support would be really nice).
|
Girls and Guys no thanks anymore - please. It clutters my mail and I really do not want to un-follow this issue. If you feel thankful, go and fix a typo, or bug, or simply be nice to whoever you meet next. |
I have put up a pull-request with a suggestion for documenting R6 classes. Essentially, it is close to how rc-classes are documented, i.e. with a docstring. But instead of a single string, it allows several strings, using @param to describe parameters and sets a usage statement inside every class method (as longer methods aren't appropriately set in the first part of a \item due to line-breaks not being possible there, I think). Would be great to get feedback. Thanks |
@hhoeflin cool! Have you put an example of a R6 class documentation somewhere (source and Rd)? I've looked at the PR but it'd be easier to see an example before giving feedback. |
An example is attached at the pull request |
@hhoeflin I'm sorry I had only looked at the code 😀 I think it'd be nice to document methods in methods as you do in this suggestion. How would you document fields? |
Fields get documented the same way as in rc classes. At the top of the R6class with a @field tag. |
One thing that I currently don't like though: I stuck to the convention of using "docstrings", i.e. strings at the beginning of a function. That is not so nice as then it is necessary to escape all slashes that are used for rd-commands. An alternative would be to document it as before using comments, parse the functions keeping the source there and then extract the comments from the function source. |
Here is another example: The tricks:
The rendered docs looks very much like regular R documentation, and you can write whatever you like in Anyway, I think we have enough examples now, so I can close this issue. |
Somewhat related to #2. It would be nice to have an example of the best practices for documenting R6 classes with and/or without roxygen2.
The text was updated successfully, but these errors were encountered: