【问题标题】:Can we combine S3 flexibility with S4 representation checking?我们可以将 S3 灵活性与 S4 表示检查结合起来吗?
【发布时间】:2016-07-21 15:48:41
【问题描述】:

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

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

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

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

我的问题是:

  • 我想吃蛋糕吗(S3 灵活性和 S4 表示检查)?在这种情况下,我需要在我的包的所有方法中添加我的 validate 函数吗?
  • 或者在 S3 之上是否有更智能的方法,例如“任何时候我们对特定类的对象执行某项操作时,对其调用 validate 函数”?

【问题讨论】:

    标签: r class packages


    【解决方案1】:

    最简单的方法是为每个类编写一个验证函数,并在 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
    

    【讨论】:

    • 我已经有了这样的a thing,但我想知道是否可以避免到处添加它。在print 中创建它是非常好的技巧!
    • @VincentBonhomme 这就是 S3 与 S4 的权衡。您必须手动验证,因为 S3 实际上只是分派了类属性;它没有为任何类型的验证提供其他基础设施。
    猜你喜欢
    • 1970-01-01
    • 2014-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-08
    相关资源
    最近更新 更多