nathaneastwood
nathaneastwood

Reputation: 3764

The correct way of accessing S3methods from the NAMESPACE

TL;DR version:

Why are the base R methods exported differently to the way the Roxygen2 authors recommend you export your own methods?

Further explanation:

This is a follow up question to the posts that can be found here and here. Rather than bombard Hadley with lots of questions, I figured it would be best to ask the community.

I am trying to understand the behaviour of S3method exports a little better as there seems to be inconsistency between the way the base R methods are exported and the way the Roxygen2 authors recommend they should be exported.

For example, within the stats package lies the plot.ts and plot.stepfun methods, among others. You can also edit() or fix() these. However with the recommended way of working in Roxygen2 it is suggested that you @export all generics and methods (Hadley's answer here).

So, let's say we have an object of class my_class and we wish to create a plot function which works for this class, plot.my_class. We can create the Roxygen2 documentation as follows:

#' plot.my_class title
#'
#' @param x An object of class 'my_class'.
#'
#' @export
plot.my_class <- function (x, ...) # some magic

This generates the NAMESPACE entry

S3method(plot,my_class)

Now, when I install the package, I will not be able to see the method plot.my_class when I use ls() on my package position in search(), nor can I edit() or fix() it (I can use getAnywhere()). Clearly this is different behaviour to that of the base R functions since I can edit(plot.ts) and see it listed within the stats package namespace. The only way I can see to get around this is to explicitly @export plot.my_class in my Roxygen2 documentation, e.g.

#' plot.my_class title
#'
#' @param x An object of class 'my_class'.
#'
#' @export plot.my_class
plot.my_class <- function (x, ...) # some magic

Which generates the - clearly wrong - NAMESPACE entry

export(plot.my_class)

Hadley says that using edit() or fix() is a bad idea. I understand some reasons why that is (maybe someone can expand a little?) but they are useful for debugging purposes since the functions I am working with are very complex.

So to conclude, why are there differences in the way base R's methods are viewable and my own methods are not?

Upvotes: 3

Views: 115

Answers (1)

Konrad Rudolph
Konrad Rudolph

Reputation: 545598

I suspect it’s for the same reason that there are lots of other inconsistencies in the base R packages: it is an organic system that grew over many years, and many aspects are very old and preserve compatibility with the S language.

Many of the guidelines that roxygen2 and other packages recommend have grown out of the experience gained from many years of working with R.

If the base R packages were rewritten from scratch today with no regards for backwards compatibility, they would look very different.

If you find yourself needing edit and/or fix to muck around in other peoples’ packages then this suggests that these packages have some major issues that should be resolved. Normally you should not need to do this — this is part of the reason for why fix is a bad idea: it’s symptomatic of an underlying problem.

In fact, even with Hadley’s recommended mode of exporting package generics it’s still possible (albeit more difficult) to hack around in the non-exported methods of the package.

Upvotes: 1

Related Questions