In S4 I might do something like this:
setClass(
"test", slots=c(a="integer"),
validity=function(object) if(length(object@a) != 1L) "not scalar" else TRUE
)
What is the equivalent for reference classes? I could not find any references to validity functions in the context of reference classes. Must I rely on defining setter classes? Though based on this comment in the reference class docs:
A number of systems using the OOP programming paradigm recommend or enforce getter and setter methods corresponding to each field, rather than direct access by name. If you like this style and want to extract a field named abc by x$getAbc() and assign it by x$setAbc(value), the $accessors method is a convenience function that creates such getter and setter methods for the specified fields. Otherwise there is no reason to use this mechanism.
it would seem there should be another way.
It's possible to set a validity method on the reference class
.A <- setRefClass("A", fields=list(x="numeric"))
setValidity("A", function(object) {
if (length(object$x) != 1)
"'x' must be length 1"
else TRUE
})
but it's not invoked under all circumstances where it might be useful
> .A()
Reference class object of class "A"
Field "x":
numeric(0)
> .A(x=1:5)
Reference class object of class "A"
Field "x":
[1] 1 2 3 4 5
> validObject(.A(x=1:5))
Error in validObject(.A(x = 1:5)) :
invalid class "A" object: 'x' must be length 1
In some ways this is no different / less quirky than S4
.B <- setClass("B", representation(x="numeric"))
setValidity("B", function(object) {
if (length(object@x) != 1)
"'x' must be length 1"
else TRUE
})
with
> .B() # no validity checking!
An object of class "B"
Slot "x":
numeric(0)
> validObject(.B())
Error in validObject(.B()) :
invalid class "B" object: 'x' must be length 1
> .B(x=1:5)
Error in validObject(.Object) :
invalid class "B" object: 'x' must be length 1
> b = .B(x=1L)
> b@x <- 1:5 # no validity checking@!
> validObject(b)
Error in validObject(b) : invalid class "B" object: 'x' must be length 1