setValidity
and explicit calls to validObject
can be used on reference classes, too,
A <- setRefClass("A", fields=list(x="numeric"))
setValidity("A", function(object) {
if (length(object$x) != 1L || !all(object$x < 11))
"'x' must be length 1 and < 11"
else NULL
})
and then
> a = A(x=11)
> validObject(a)
Error in validObject(a) :
invalid class "A" object: 'x' must be length 1 and < 11
but in some ways your direct field access is the same as direct slot access
B <- setClass("B", representation(x="numeric"))
setValidity("B", function(object) {
if (length(object@x) != 1L || !all(object@x < 11))
"'x' must be length 1 and < 11"
else NULL
})
with
> b = B()
> b@x = 11 # no validObject check, just like direct field assignment
> validObject(b)
Error in validObject(b) :
invalid class "B" object: 'x' must be length 1 and < 11
So as a programming discipline using the accessor that you've defined, test$setFirstValue(11)
, seems to be the best approach to imposing additional validity conditions.
S4 classes have the usual semantics of R -- appearance of copy on change -- whereas reference classes have reference semantics; this is the main difference and driving force in determining appropriate class system to use, even though performance differences are also present.