Exporting and importing S3 method between packages
Asked Answered
C

0

8

Disclaimer: I found the solution to this problem when writing this question. But my question now is "How does it work?"

I am trying to export S3 method from one package (say pkg.from) and import it into another package (say pkg.to). To export the method I use roxygen2 comments.

#' @export
myclass <- function() {
  structure(NULL, class = 'myclass')
}

#' @export
print.myclass <- function(x, ...) {
  print('NULL with class myclass')
}

File NAMESPACE now contains both the constructor and method.

S3method(print,myclass)
export(myclass)

I believe that means both of them are exported. This supports the fact that I can call both after loading the package.

library(pkg.from)
methods(print)
# ...
# [130] print.myclass*
# ...
print(myclass())
# [1] "NULL with class myclass"

The problem is when I want to import this method into the other package using roxygen2.

#' @importFrom pkg.from print.myclass

During Build this message occurs:

Error : object 'print.myclass' is not exported by 'namespace:pkg.from'
ERROR: lazy loading failed for package 'pkg.to'

If I don't import print.myclass it works even if I don't have package pkg.from loaded. Hadley Wickham writes "you don’t need to do anything special for S3 methods". But I don't think importing a function is "anything special". Now I have more questions then I had when started writing this question.

  • Where does R stores the methods available for every generic?
  • How can one solve conflicts when he has installed more packages with the same method for a class?
Cardigan answered 22/3, 2017 at 12:54 Comment(1)
I have the same issue. I want to extend an existing (base) generic in package A. Just using #' @export does not seem to allow me to use the new method in another package B unless I list package A in "depends" of package B. I only want to list it in "imports", as is generally recommended.Dhiman

© 2022 - 2024 — McMap. All rights reserved.