何时初始化检查对象的有效性?

问题描述 投票:1回答:1

来自钱伯斯(出色)Extending R (2016)

一个有效性方法将从initialize()的默认方法中自动调用。推荐的初始化方法形式以callNextMethod()调用结尾,以确保可以在对类的生成器的调用中指定子类插槽。如果遵循此约定,则初始化将以对默认方法的调用结束,并且将在发生所有初始化之后调用有效方法。

我以为我理解了,但是我得到的行为似乎并不遵循这个约定。

setClass("A", slots = c(s1 = "numeric"))

setValidity("A", function(object) {
  if (length(object@s1) > 5) {
    return("s1 longer than 5")
  }
  TRUE
})

setMethod("initialize", "A", function(.Object, s1, ...) {
  if (!missing(s1)) .Object@s1 <- s1 + 4
  callNextMethod(.Object, ...)
})

A <- new("A", rep(1.0, 6))
A
# An object of class "A"
# Slot "s1":
#   [1] 5 5 5 5 5 5
validObject(A)
# Error in validObject(A) : invalid class “A” object: s1 longer than 5

我希望通过在初始化方法的末尾添加callNextMethod()来进行有效性检查。在validObject(.Object)起作用之前添加一个显式的callNextMethod(),但我在这里显然不明白。

显然,我也可以在有效性方法中进行所有相同的检查,但是理想情况下,所有有效性检查都将在setValidity内进行,因此以后的编辑将放在一个地方。

略微更改initialize函数会产生所需的结果-是否有理由使用一种方法而不是另一种方法?钱伯斯似乎更喜欢使用.Object@<-,而我在其他地方也看到了以下方法(Gentlemman和Hadley)。

setMethod("initialize", "A", function(.Object, s1, ...) {
  if (!missing(s1)) s1 + 4
  else s1 <- numeric()
  callNextMethod(.Object, s1 = s1, ...)
})
r s4
1个回答
0
投票

也许最好的指南来自initialize本身-如果您检查默认方法的代码

getMethod("initialize",signature(.Object="ANY"))

然后您看到它确实确实包含对validObject的显式调用:

...
    validObject(.Object)
  }
  .Object
}

因此,如果您定义自己的initialize方法,则最可能要做的就是在返回.Object之前在方法末尾调用它。

© www.soinside.com 2019 - 2024. All rights reserved.