I am working on a custom R6Class
which will be the main structure of my R package. But the problem is that this:
setMethod('+', signature("MyClass"), function(e1, e2)1)
or
setMethod('+', signature("R6"), function(e1, e2)1)
are not working because when I run
a = MyClass$new()
a + a
I get the following error Error in a + a : non-numeric argument to binary operator
The only way I got it working is like this
`+.MyClass` = function(e1, e2) { return (1) }
but this is not useful since when load the package from scratch (library(MyClass)
) on an empty environment +.MyClass
is not defined.
So, how can operators for R6 classes be overloaded the right way?
Just in case, the snippet:
MyClass = R6Class(
"MyClass",
public = list(
initialize = function() {
}
),
private = list(
)
)
setMethod('+', signature("MyClass"), function(e1, e2)1)
a = MyClass$new()
a+a
When you load the package, +.MyClass
should absolutely be available, assuming you've exported the function.1
I can demonstrate this with a minimal example, for which I used devtools
-- I can't recommend enough the use of devtools for package creation. First, I create a minimal package structure:
devtools::create("dummypack", rstudio = FALSE)
Then I add a single R file in the "dummypack/R/" folder, "MyClass.R":
#' @export
MyClass = R6::R6Class(
"MyClass",
public = list(
initialize = function() {
}
),
private = list(
)
)
#' @export
`+.MyClass` = function(e1, e2) { return (1) }
The #' @export
tags here are critical;2 what you need for this function to be available is that it is exported in the "dummypack/NAMESPACE" file (see the Namespaces chapter of Hadley Wickham's R packages). You need your NAMESPACE file to look like
export(MyClass)
export(`+.MyClass`)
to make sure both the class and the overloaded +
operator are exported. Alternatively you could have a NAMESPACE like
exportPattern("^[^\\.]")
to export everything that does not begin with a .
(this is the NAMESPACE file initially generated by devtools::create()
). So, if you are not using devtools
(and Roxygen -- roxygen2
), you need to edit the NAMESPACE file yourself to make sure your functions are exported.
Then I run
devtools::install("dummypack/")
and in a fresh R session I run:
library(dummypack)
a = MyClass$new()
a+a
# [1] 1
to show that you get the result you'd want.
2 Note that those tags only help with your NAMESPACE file if you are using Roxygen (which would work if you were using devtools::document()
). Also, for the minimal example I show, the tags aren't technically necessary since the default NAMESPACE generated by devtools::create()
just has the line exportPattern("^[^\\.]")
as discussed above. However, in the typical case you want these tags and either way the important thing is what ends up in the NAMESPACE file -- you need explicit export()
statements in NAMESPACE or a statement such as exportPattern("^[^\\.]")
.