Skip to content
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

Vignette for roxygen documentation of an S7 class and method #528

Open
tripartio opened this issue Feb 17, 2025 · 1 comment
Open

Vignette for roxygen documentation of an S7 class and method #528

tripartio opened this issue Feb 17, 2025 · 1 comment

Comments

@tripartio
Copy link

tripartio commented Feb 17, 2025

I struggled quite a bit learning how to document my S7 class and methods. I finally figured it out, partially by duplicating the demonstration Range class from an S7 vignette. I figured I could develop my demo and (with some help from ChatGPT) offer it as a first draft for a new S7 vignette proposal for how to document an S7 class using roxygen. I would think it makes more sense adding such a vignette to the S7 site than to the roxygen site because I think this is where people new to S7 would look first.

Although the documentation works (I reproduce images from R help to show the results), there are probably better ways to do things than in this draft, so I hope I can learn from any corrections. In particular, I'm really not sure about naming the print method print.Range in S3 style. But at least it works.

For convenience of viewing, I will post the entire Quarto code in the next comment so that it is rendered. I hope that's OK. (Also, I generated this Range demo within my development version of the ale package, so that name appears in my draft below.)

So, to be clear, the purpose of this issue is to request a new vignette; I offer a first draft for discussion and correction.

@tripartio
Copy link
Author


title: "Documenting an S7 Class with roxygen"
format: html

Introduction

This vignette demonstrates how to document an S7 class using roxygen. Our example is a simple Range class that computes the numeric range (i.e., the minimum and maximum values) of a vector. The focus here is not on the S7 system itself but rather on explaining the details of roxygen documentation for an S7 class.

The complete code

Below is the full code for the Range class and its print method, complete with roxygen documentation. Copying and running this code (with the appropriate S7 infrastructure) would create a documented S7 class in your package.

# Range S7 class documentation

#' Range Class
#'
#' An S7 class representing a numeric range computed from a vector. The class calculates
#' the minimum and maximum values from the provided numeric vector, storing them as `start`
#' and `end`, respectively.
#'
#' @param x A numeric vector from which the range is computed. Missing values are removed
#'   before computing the range.
#'
#' @returns An object of class `Range` with properties `start` and `end`.
#'
#' @section Properties:
#' \describe{
#'   \item{start}{A numeric value representing the minimum value of the input vector.}
#'   \item{end}{A numeric value representing the maximum value of the input vector.}
#' }
#'
#' @examples
#' # Create a Range object from a numeric vector:
#' r <- Range(1:10)
#' str(r)
#'
#' @export
Range <- new_class(
  "Range",
  properties = list(
    start = class_numeric,
    end = class_numeric
  ),
  constructor = function(x) {
    new_object(
      S7_object(),
      start = min(x, na.rm = TRUE),
      end = max(x, na.rm = TRUE)
    )
  }
)

#' @name print.Range
#' @title print Method for Range object
#'
#' @description
#' Print a Range object.
#'
#' @param x An object of class `Range`.
#' @param ... Additional arguments (currently not used).
#'
#' @returns Invisibly returns `x`.
#'
#' @examples
#' r <- Range(c(3, -2, 0, 10, 5))
#' r  # implicit print
#' print(r)  # explicit print
#'
#' @method print Range
method(print, Range) <- function(x, ...) {
  cat(
    "'Range' object from ", x@start, " to ", x@end, "\n",
    sep = ''
  )
  invisible(x)
}

Documentation for the Range S7 class

First, it helps to see what the compiled documentation from above looks like in the R help system. Here's the documentation for the Range class, obtained by typing ?Range:

R help documentation of the Range class

Let’s break down each part of the roxygen documentation used in the example:

  • Title and Description\
#' Range Class
#' 
#' An S7 class representing a numeric range computed from a vector. The class calculates
#' the minimum and maximum values from the provided numeric vector, storing them as `start`
#' and `end`, respectively.
  • The first line (#' Range Class) acts as the title. It’s what users see as the main heading in the generated help file.

  • The following lines provide a brief description of what the Range class does.

  • Parameter (@param)

    #' @param x A numeric vector from which the range is computed. Missing values are removed
    #'   before computing the range.
  • This tag documents the input parameter x used by the class constructor.

  • It explains the type of data expected (a numeric vector) and mentions how missing values are handled.

  • Return Value (@return)

    #' @returns An object of class `Range` with properties `start` and `end`.
  • Describes what the constructor returns. In this case, it returns a Range object containing two properties: start and end.

  • Section for Properties (@section)

    #' @section Properties:
    #' \describe{
    #'   \item{start}{A numeric value representing the minimum value of the input vector.}
    #'   \item{end}{A numeric value representing the maximum value of the input vector.}
    #' }
  • The @section tag introduces a new section titled "Properties".

  • Inside, we use \describe{} to create a list that describes each property (start and end) in detail.

  • Examples (@examples)

    #' @examples
    #' # Create a Range object from a numeric vector:
    #' r <- Range(1:10)
    #' str(r)
  • Provides code examples that show how to create and inspect a Range object.

  • These examples are executed during package checks and help users understand how to use the function.

  • Exporting (@export)

    #' @export
  • This tag ensures that the Range class is exported when the package is built. It makes the function available to package users rather than only being internal to the package.

Documentation for an S7 method

As before, we first show what a documented method looks like. We use a simple print method for demonstration; its documentation is obtained by typing ?print.Range:

R help documentation of the print method for Range objects

  • Name and Title

    #' @name print.Range
    #' @title print Method for Range object
  • @name assigns a unique topic name for the documentation (in this case, linking it to the print method for Range objects). method.S3_class is the standard S3 format for method names. Although this is not how S7 classes are explicitly referred to, for roxygen to be able to create a named topic, this S3 name format can be used for the S7 method, taking advantage of S7's continuity with S3.

    • @title provides a concise title for the print method documentation.
  • Description

    #' @description
    #' Print a Range object.
  • Briefly explains what the method does—printing a Range object.

  • Parameters for the Method (@param)

    #' @param x An object of class `Range`.
    #' @param ... Additional arguments (currently not used).
  • Documents the parameters of the print method. Here, x is the object to be printed, and ... is provided for additional arguments even though it isn’t used.

  • Return Value (@return)

    #' @returns Invisibly returns `x`.
  • Specifies that the method returns the input object invisibly (i.e., without printing it again).

  • Examples (@examples)

    #' @examples
    #' r <- Range(c(3, -2, 0, 10, 5))
    #' r  # implicit print
    #' print(r)  # explicit print
  • Offers examples that illustrate both implicit and explicit calls to the print method.

  • Method Assignment (@method)

    #' @method print Range
  • This tag formally registers the function as the print method for objects of class Range.

Running the Example

If you have a package that supports S7 classes and you process your documentation using roxygen2, this code will generate help files that users can access by typing, for example, ?Range and ?print.Range in R.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant