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?
#' @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