• R语言
  • S4中initialize函数和对象检查的运行顺序问题

请问在S4中,initialize函数和对象检查机制(validity)的运行顺序是什么?举一个例子说明我的疑问:

<br />
# definition of "testClass"<br />
setClass(<br />
         Class = "testClass",<br />
         representation = representation(Nor = "numeric", Con = "character"),<br />
         validity = function(object){<br />
           if (length(object@Nor) != length(object@Con)){<br />
             stop("Hello, it is wrong!")<br />
           } else TRUE<br />
         }<br />
         )</p>
<p># initialize method for "testClass"<br />
setMethod(<br />
          f = "initialize",<br />
          signature = "testClass",<br />
          definition = function(.Object, Nor, Con){<br />
            if (!missing(Nor)){<br />
              names(Nor) <- letters[1:length(Nor)]<br />
              .Object@Nor <- Nor<br />
              .Object@Con <- Con<br />
            }<br />
            return(.Object)<br />
          }<br />
          )</p>
<p># a right object<br />
new("testClass", Nor = 1:5, Con = letters[1:5])<br />
## An object of class "testClass"<br />
## Slot "Nor":<br />
## a b c d e<br />
## 1 2 3 4 5 </p>
<p>## Slot "Con":<br />
## [1] "a" "b" "c" "d" "e"</p>
<p># a wrong object<br />
new("testClass", Nor = 1:3, Con = letters[1:5])<br />
## An object of class "testClass"<br />
## Slot "Nor":<br />
## a b c<br />
## 1 2 3 </p>
<p>## Slot "Con":<br />
## [1] "a" "b" "c" "d" "e"<br />


很明显,如果这样设定initialize函数,建立的对象逃过了检查。这说明使用自己设定的initialize函数,检查机制没有运行或者没有发挥作用。解决办法是设定initialize函数时,加上validObject()函数,比如:
<br />
setMethod(<br />
          f = "initialize",<br />
          signature = "testClass",<br />
          definition = function(.Object, Nor, Con){<br />
            if (!missing(Nor)){<br />
              names(Nor) <- letters[1:length(Nor)]<br />
              .Object@Nor <- Nor<br />
              .Object@Con <- Con<br />
              validObject(.Object)<br />
            }<br />
            return(.Object)<br />
          }<br />
          )</p>
<p>new("testClass", Nor = 1:3, Con = letters[1:5])<br />
## 错误于validityMethod(object) : Hello, it is wrong!<br />
</p>

当然,还有一个解决办法是使用callNextMethod(),比如:

<br />
setMethod(<br />
          f = "initialize",<br />
          signature = "testClass",<br />
          definition = function(.Object, ...){<br />
            .Object <- callNextMethod()<br />
            if (length(.Object@Nor) != 0)<br />
              names(.Object@Nor) <- letters[1:length(.Object@Nor)]<br />
            return(.Object)<br />
          }<br />
          )</p>
<p>new("testClass", Nor = 1:3, Con = letters[1:5])<br />
## 错误于validityMethod(object) : Hello, it is wrong!<br />


这时,我就感到疑惑了。因为在使用callNextMethod()函数时,调用了“默认”的initialize函数(也可能我理解错误,callNextMethod()调用的不是默认函数,而是其他。如是,请批评指正),对象检查机制正常运行。因此,为什么自己设定的intialize函数没有运行检查机制,而默认的函数却运行了。initialize函数和对象检查机制的运行顺序究竟是什么呢?
</p>

回复 第1楼 的 foshuochanyu:[s:12] 自己回复自己帖子。鼓捣了一晚上,搞定了这个疑问。默认initialize函数(signature = "ANY")确实调用了validObject()函数,查看源码

getMethod(f = "initialize", signature = "ANY")
因此在使用callNextMethod()时,对象检查机制正常运行。
</p>