I have an R6
class and I want to add an S3
method for it. The documentation I found mentioned briefly that in order to use S3
dispatch on R6
you must have class = TRUE
, but I couldn't find an example of how it should be done.
I did see empirically that simply writing an S3 method in the form s3generic.r6class
worked, but I wanted to know if that is indeed to right way to write an S3
method for R6
.
For example, say I have an R6
class that enhances a list
library(R6)
R6list <- R6Class(
"R6list",
public = list(
orig = NULL,
initialize = function(x) {
self$orig <- x
}
)
)
Question 1
Naturally, I want to provide a method for obtaining the underlying list, so I wanted to add an as.list
method. Is it standard to add both an S3 generic AND a as.list
public function inside the class? My intuitive answer is to add both.
R6list <- R6Class(
"R6list",
public = list(
orig = NULL,
initialize = function(x) {
self$orig <- x
},
as.list = function() {
self$orig
}
)
)
as.list.R6list <- function(x, ...) {
x$as.list()
}
So that now if I have an object mylist <- R6list$new(as.list(letters[1:5]))
I can either call as.list(mylist)
or mylist$as.list()
. Is one of those preferred over the other?
Question 2
Is there anything special about writing an S3
method for R6
classes, or is what I wrote above sufficient and the correct way? I wasn't sure if the S3
method has to be written outside of the class definition, or if R6
somehow provides a way to write S3
methods within it so that all the code relating to the class is localized.
S3 refers to a class system built into R. The system governs how R handles objects of different classes. Certain R functions will look up an object's S3 class, and then behave differently in response. The print function is like this.
S3 implements a style of object oriented programming called generic-function OO. This is different to most programming languages, like Java, C++ and C#, which implement message-passing OO. In message-passing style, messages (methods) are sent to objects and the object determines which function to call.
Create a new R6 class object that on multipication of numbers. The class name and the result of class must be same always, as the R6Class() returns a R6 object that defines the class. We can then construct a new object from the class using the new() method which is accessed using the $ operator.
A constructor is a special method that's executed whenever you create a new object of the class. So, each time you run d <- Dog$new() , a new instance of the Dog class is created, and therefore, the constructor method is executed. In R and R6, the constructor is defined with the initialize function.
I asked Winston Chang, the author of R6
, about this on Github. According to him, the code provided in Question 1 above is the correct way of writing S3 methods for R6 classes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With