Using R6, I would like to enforce that a method returns a particular data-type, Is this possible?
For Instance, consider the following:
A = R6::R6Class("ClassA",
public=list(
getx = function() as.integer(1)
)
)
B = R6::R6Class("ClassB",inherit=A,
public = list(
getx = function() "ABCDEF"
)
)
If I wanted to enforce the function getx()
to return an integer, an instance of A is fine, but I want to prevent a subclass from returning a different type, such as the case for B. In other words, I want a function to have consistency in what it returns, regardless of where it is actually implemented.
You can do this with a workaround. Directly it is not possible, indirectly using a second function, it is.
When you define the new "getx" function in "ClassB", this completely hides the function "getx" from Class A. There is no mechanism in R6 to ensure that any return value has to pass through a particular function.
Now - what you can do is the following:
Let getx from ClassA be the public function. All it does is call a private function p_getx that actually returns the value and getx just coerces it to the right type.
Then any user implementing a ClassB inheriting from ClassA would leave the public function getx unchanged and instead implement the private method p_getx. This is the model the 'clone' method uses w.r.t. private 'deep_clone' methods.
Some example code
ClassA <- R6Class("ClassA",
public=list(
getx = function() {
return(as.character(private$p_getx()))
}
),
private=list(
p_getx = function() {
return("ClassA")
}
)
)
ClassB <- R6Class("ClassB", inherit = ClassA,
private=list(
p_getx = function() {
return(factor("ClassB"))
}
)
)
obj_A <- ClassA$new()
obj_B <- ClassB$new()
with output
> obj_A$getx()
[1] "ClassA"
> class(obj_A$getx())
[1] "character"
> obj_B$getx()
[1] "ClassB"
> class(obj_B$getx())
[1] "character"