我们可以将 S3 灵活性与 S4 表示检查结合起来吗?

Can we combine S3 flexibility with S4 representation checking?

我正在寻找一种方法来验证我的包中的 S3 对象 Momocs

包的早期版本是使用 S4 编写的,然后为了灵活性,我转回了 S3,因为用户更喜欢 S3,因为我真的不需要多重继承,etc.。此更改的主要成本实际上是失去了 S4 表示/有效性检查。

我的问题如下:我们如何防止无意中 "unvalidate" S3 对象,例如试图扩展现有方法或操纵对象结构?

我已经编写了一些 validate 函数,但到目前为止,我只在关键步骤之前进行验证,通常是那些将对象从 class 转换为另一个对象的步骤。

我的问题是:

最简单的方法是为每个 class 编写一个验证函数,并在 S3 方法分派之前或在每个 class 的方法中通过它传递对象。下面是一个简单的验证函数示例,名为 check_example_class 用于 class "example_class":

的对象
check_example_class <- function(x) {
  stopifnot(length(x) == 2)
  stopifnot("a" %in% names(x))
  stopifnot("b" %in% names(x))
  stopifnot(is.numeric(x$a))
  stopifnot(is.character(x$b))
  NULL
}
print.example_class <- function(x, ...) {
    check_example_class(x)
    cat("Example class object where b =", x$b, "\n")
    invisible(x)
}

# an object of the class
good <- structure(list(a = 1, b = "foo"), class = "example_class")

# an object that pretends to be of the class
bad <- structure(1, class = "example_class")

print(good) # works
## Example class object where b = foo
print(bad)  # fails
## Error: length(x) == 2 is not TRUE