R S4 继承 - 有效性测试和可选插槽的问题

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

我正在尝试创建一个包含另一个具有可选插槽的类 A 的类 B(即使在定义类 A 时没有传递任何参数,也应该创建该对象):

定义A类并创建实例时,有效性测试没问题(检测空槽是可以的):

setClass("A",
         slots = c(x="numeric", y = "character"),
         prototype = list(
           x = numeric(0),
           y = character(0)
         ),
         validity=function(object){
           if(length(object@x) == 0){
             warning("x slot is empty")
           }
           if(length(object@y) == 0){
             warning("y slot is empty")
           }
           return(TRUE)
         })

setMethod("initialize", signature = "A",
          definition = function(.Object, x, y)
          {
            if (!missing(x)) {
              .Object@x <- x
            } else {
              .Object@x <- numeric(0)
            }
            if (!missing(y)) {
              .Object@y <- y
            } else {
              .Object@y <- character(0)
            }
            validObject(.Object)
            return(.Object)
          } )

new("A", x=1:10)
# warning message "validityMethod(object) : y slot is empty"

但是当如下创建 B 类对象时,即使传递了参数,我也会收到有效性消息,并且它们是重复的:

setClass("B",
         slots = c(a = "data.frame"),
         contains = "A",
         validity = function(object) {
           if (length(object@a) == 0) {
             warning("a is empty")
           }
           return(TRUE)
           })

setMethod("initialize", signature = "B",
          definition = function(.Object, a, ...)
          {
            .Object@a <- a
            .Object <- callNextMethod(.Object, ...)
            validObject(.Object)
            return(.Object)
          } )

new("B", a = data.frame(10), x = 5, y = "c")

# gives warning messages: 
#1: in validityMethod(object) : x slot is empty
#2: in validityMethod(object) : y slot is empty
#3: in validityMethod(object) : x slot is empty
#4: in validityMethod(object) : y slot is empty

当某个参数确实缺失时,我会收到附加消息(再次重复):

new("B", a = data.frame(10), x = 5)

# warning:
#
#1: in validityMethod(object) : x slot is empty
#2: in validityMethod(object) : y slot is empty
#3: in validityMethod(as(object, superClass)) : y slot is empty
#4: in validityMethod(object) : x slot is empty
#5: in validityMethod(object) : y slot is empty
#6: in validityMethod(as(object, superClass)) : y slot is empty

如何避免这些重复的消息并使它们起作用(仅当参数确实丢失时)?

r oop inheritance r-s4
1个回答
0
投票

一些事情:

  • 有效性方法应返回
    TRUE
    或字符串,而不是信号条件。 条件信号由
    validObject
    处理,而不是有效性方法本身。 在任何情况下,正式类的对象都是有效或无效的,因此在有效性方法中抛出警告(表明对象可以是准有效或准无效)确实是不寻常的。
  • 零长度原型是自动的,所以你不需要在这里设置
    prototype=
  • 您的
    if (<missing>) <assign prototype> else <assign value>
    方法中的
    initialize
    模式是拼凑的。 默认方法已经完成了所有这些工作,因此请分派给它。

将所有内容放在一起:

setClass("A", slots = c(x = "numeric", y = "character"))
setMethod("initialize", "A",
          function(.Object, ...) {
              .Object <- callNextMethod()
              if (length(.Object@x) == 0L)
                  warning("zero-length 'x' slot")
              if (length(.Object@y) == 0L)
                  warning("zero-length 'y' slot")
              .Object
          })

setClass("B", contains = "A", slots = c(a = "data.frame"))
setMethod("initialize", "B",
          function(.Object, ...) {
              .Object <- callNextMethod()
              if (length(.Object@a) == 0L)
                  warning("zero-length 'a' slot")
              .Object
          })
> new("A")
An object of class "A"
Slot "x":
numeric(0)

Slot "y":
character(0)

Warning messages:
1: In initialize(value, ...) : zero-length 'x' slot
2: In initialize(value, ...) : zero-length 'y' slot
> new("B")
An object of class "B"
Slot "a":
data frame with 0 columns and 0 rows

Slot "x":
numeric(0)

Slot "y":
character(0)

Warning messages:
1: In .nextMethod(.Object = .Object) : zero-length 'x' slot
2: In .nextMethod(.Object = .Object) : zero-length 'y' slot
3: In initialize(value, ...) : zero-length 'a' slot
> new("B", y = "")
An object of class "B"
Slot "a":
data frame with 0 columns and 0 rows

Slot "x":
numeric(0)

Slot "y":
[1] ""

Warning messages:
1: In .nextMethod(.Object = .Object, ... = ...) : zero-length 'x' slot
2: In initialize(value, ...) : zero-length 'a' slot
© www.soinside.com 2019 - 2024. All rights reserved.