Hypothesis
Roxygen2 uses a heuristic. If the prefix preceding the period is known (merge
, cut
), the method is an S3 method, otherwise (slice
), it is an ordinary method.
Question
Is this heuristic documented? More importantly, is there a way to avert it? I should be able to write any unused identifier for a function name, without watching out for prefixes, which would also mean that there would be no future guarantees that one can offer regarding the stability of a given package. I understand that "S3 classes have no formal definition" (last vignette cited below), but it seems absurd to mess with what does have a formal definition. Plus, any future edits of a package to use a new package can suddenly make it necessary to invalidate an existing API.
I tried to fix this by editing the NAMESPACE
file by hand after it is generated, but this sometimes messes up with package installation (in a way I don't yet understand). The following experiment is the setup for the question.
Experiment
After running devtools::create("MyPackage")
, put the following code
#' @export
merge.apples <- function() {}
#' @export
merge.oranges <- function() {}
#' @export
cut.apples <- function() {}
#' @export
cut.oranges <- function() {}
#' @export
slice.apples <- function() {}
#' @export
slice.oranges <- function() {}
in MyPackage/R/somefile.R
.
Now run devtools::document()
(twice). You will see that the contents
# Generated by roxygen2: do not edit by hand
S3method(cut,apples)
S3method(cut,oranges)
S3method(merge,apples)
S3method(merge,oranges)
export(slice.apples)
export(slice.oranges)
have been generated in the file MyPackage/NAMESPACE
. In other words, four functions have been assumed to be S3 functions.
From the pages
vignette("namespace", package = "roxygen2")
vignette("roxygen2", package = "roxygen2")
vignette("rd", package = "roxygen2")
it is now (since circa 2014?) sufficient to write #' @export
before either an S3 method or an ordinary method, and roxygen2
will figure out which it is.