如何检查引用类中的字段分配

时间:2013-03-15 06:49:25

标签: r oop reference-class

我对参考类有疑问。如何查看字段分配。

这是我的示例代码:

rm(list=ls(all=TRUE))

setRefClass(
    Class = "A", 
    fields = list(firstValue = "numeric"),
    methods = list(

        initialize = function(..., firstValue = numeric()) {
            setFirstValue(firstValue)
        },

        getFirstValue = function() {
            return(firstValue)
        },

        setFirstValue = function(value) {
            if(length(value) != 0) {
                if(value > 10) {
                    cat("only values lower 10 allowed!\n")
                    firstValue <<- 10
                } else {
                    firstValue <<- value
                }
            } else {
                firstValue <<- 0
            }
        }               
    )
)

test <- getRefClass("A")$new()
test$getFirstValue()
test$firstValue
test$setFirstValue(11)
test$firstValue
test$firstValue <- 11
test$firstValue

我的问题是如何防止它,设置“test $ firstValue&lt; -11”而不检查值。 在S4中,我会这样解决:

setGeneric(name = 'setFirstValue<-', def = function(object, value) {standardGeneric('setFirstValue<-')})
setReplaceMethod(
        f = 'setFirstValue',
        signature = 'A',
        definition = function(object, value) {
            object@.firstValue <- value
            validObject(object)
            return(object)
        }
)

and

setReplaceMethod(
    f = "[",
    signature = "A",
    definition = function(x, i ,j , value) {
        if(i == 'firstValue ' || i == 1) {setFirstValue(x) <- value}
    return(x)
    }
)

最后,在“A”的类定义中,将放置“validity = function(object){ ... }”。但我如何通过参考类来解决这个问题呢?

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

setValidity并且对validObject的显式调用也可用于参考类,

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
})

然后

> a = A(x=11)
> validObject(a)
Error in validObject(a) : 
  invalid class "A" object: 'x' must be length 1 and < 11

但在某些方面,您的直接字段访问与直接插槽访问相同

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
})

> 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

因此,使用您定义的访问者test$setFirstValue(11)的编程规则似乎是强加额外有效性条件的最佳方法。

S4类具有R的通常语义 - 在更改时出现副本 - 而引用类具有引用语义;这是确定适当的班级系统使用的主要区别和驱动力,即使性能差异也存在。