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

时间:2016-04-01 18:10:37

标签: r class packages

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

该软件包的早期版本是使用S4编写的,然后我为了灵活性而转回S3,因为用户更多地使用S3,因为我不需要多重继承,etc.。这一变化的主要成本实际上是失去了S4表示/有效性检查。

我的问题如下:我们怎样才能防止人们无意中"取消验证"一个S3对象,例如尝试扩展现有方法或操纵对象结构?

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

我的问题是:

  • 我想吃蛋糕并吃掉它(S3灵活性和S4表示检查)?在这种情况下,我需要在我的包的所有方法中添加validate函数吗?
  • 或者有更聪明的方式在S3之上,类似于"每当我们对特定类的对象执行某些操作时,在其上调用validate函数"?

1 个答案:

答案 0 :(得分:2)

最简单的方法是为每个类编写验证函数,并在S3方法调度之前或在每个类的方法中通过它传递对象。这是一个示例,其中包含一个名为check_example_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