ReferenceClass的有效性检查

时间:2014-05-23 23:19:38

标签: r

S4类允许您使用validObject()setValidity()定义有效性检查。但是,这似乎不适用于ReferenceClasses。

我尝试将assert_that()if (badness) stop(message)子句添加到ReferenceClass的$initialize()方法中。但是,当我模拟加载包时(使用devtools::load_all()),它必须尝试创建一些原型类,因为initialize方法执行并失败(因为没有设置字段)。

我做错了什么?

2 个答案:

答案 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