S4类允许您使用validObject()
或setValidity()
定义有效性检查。但是,这似乎不适用于ReferenceClasses。
我尝试将assert_that()
或if (badness) stop(message)
子句添加到ReferenceClass的$initialize()
方法中。但是,当我模拟加载包时(使用devtools::load_all()
),它必须尝试创建一些原型类,因为initialize
方法执行并失败(因为没有设置字段)。
我做错了什么?
答案 0 :(得分:3)
在引用类
上实现有效性方法A = setRefClass("A", fields=list(x="numeric", y="numeric"))
setValidity("A", function(object) {
if (length(object$x) != length(object$y)) {
"x, y lengths differ"
} else NULL
})
并明确调用有效性方法
> validObject(A())
[1] TRUE
> validObject(A(x=1:5, y=5:1))
[1] TRUE
> validObject(A(x=1:5, y=5:4))
Error in validObject(A(x = 1:5, y = 5:4)) :
invalid class "A" object: x, y lengths differ
不幸的是,setValidity()
需要作为initialize方法或构造函数的倒数第二行显式调用。
答案 1 :(得分:1)
好的,你可以在initialize
中执行此操作。它应该具有以下形式:
initialize = function (...) {
if (nargs()) return ()
# Capture arguments in list
args <- list(...)
# If the field name is passed to the initialize function
# then check whether it is valid and assign it. Otherwise
# assign a zero length value (character if field_name has
# that type)
if (!is.null(args$field_name)) {
assert_that(check_field_name(args$field_name))
field_name <<- field_name
} else {
field_name <<- character()
}
# Make sure you callSuper as this will then assign other
# fields included in ... that weren't already specially
# processed like `field_name`
callSuper(...)
}
这是基于lme4包中列出的the strategy。