Exported S3 method not found during check

654 views Asked by At

In a package, I have a function foo that returns an object of class "foo". I also have a plot method for class "foo".

#' Create a "foo" object
#'
#' @param x An \R object.
#' 
#' @return
#' A "foo" object.
#'
#' @examples
#' foo_object <- foo(1)
#' plot.foo(foo_object)
#'
#' @export
foo <- function(x) {
    structure(x, class = "foo")
}

#' @export
#' @importFrom graphics plot
plot.foo <- function(x, ...) {
    class(x) <- setdiff(class(x), "foo")
    plot(x)
    invisible(NULL)
}

I can evaluate the example code without issue after I load the package with devtools::load_all. However, devtools::check complains:

Error in plot.foo(foo_out) : could not find function "plot.foo"
  Execution halted

It seems that my R session knows about plot.foo, but not devtools::check. What is going on?


Edit: To clarify, devtools::check passes when I replace the call plot.foo(foo_object) under @examples with plot(foo_object). That doesn't surprise me, and users should call the generic anyway. My question remains: why is devtools::check unable to find plot.foo, given that I have used the @export tag and S3method(plot, foo) appears in NAMESPACE after devtools::document?

1

There are 1 answers

0
MrFlick On BEST ANSWER

If you want to be able to call plot.foo directly, then you will need to explicitly export that version as well. By convention, usually you do not export class-specific implemenations of generic functions from your package. Normally you just declare that the S3 method exists and leave the function unexported. Like if you call methods(plot) you'll see a bunch with asterisks which means they are unexpected and are not meant to be called directly. If you do for some reason want to export it as a separate function, you can add an additional export statement. For example

#' @rdname foo-methods
#' @export plot.foo
#' @export
#' @importFrom graphics plot
plot.foo <- function(x, ...) {
  class(x) <- setdiff(class(x), "foo")
  plot(x)
  invisible(NULL)
}