构造函数引用类

时间:2013-09-20 12:04:40

标签: r reference-class

我喜欢以这种方式更改下面的src,初始化函数看起来像某些构造函数。我想改变下面的例子

    Part.initialize<-function(...){
  args<-list(...)
  if(all(class(args[[1]])==c("XMLInternalElementNode", "XMLInternalNode", "XMLAbstractNode"))){
    attr<-xmlAttrs(node)
    .self$var1 <- if(is.na(attr["var1"])) vector() else attr["var1"]
    .self$var2 <- if(is.na(attr["var2"])) character() else as.character(attr["var2"])
  }else{
    .self$var1 <- if(is.null(args[["var1"]])) vector() else args[["var1"]]
    .self$var2 <- if(is.null(args[["var2"]])) character() else as.character(args[["var2"]])
  }
  .self
}

Part<-setRefClass(Class = "Part"
                 ,fields = c(var1 = "ANY", var2 = "character")
                 ,methods = list(initialize=Part.initialize))

txt = "<doc> <part var2=\"abc\"/> </doc>"

tree <- xmlTreeParse(txt, useInternalNodes = TRUE)
node<-xpathSApply(tree, "//part")[[1]]
part <- Part$new(node)

类似于:

 Part.initialize<-function(XMLNode){
        do something
   }
   Part.initialize<-function(var1=c(),var2=character()){
        do something
   }

除了如何处理ANY类型的默认值?直到现在我使用vector()。

1 个答案:

答案 0 :(得分:2)

不要编写initialize方法,编写公共构造函数 (.Part:仅供代码使用的构造函数,而不是用户)。公共构造函数的工作是将用户参数转换为类方法的一致形式

.Part<-setRefClass(Class = "Part"
                  ,fields = c(var1 = "ANY", var2 = "character"))

使用setOldClass启用课程调度

setOldClass(c("XMLInternalElementNode", "XMLInternalNode",
              "XMLAbstractNode"))

将您的公共构造函数编写为S4泛型和方法

setGeneric("Part", function(x, ...) standardGeneric("Part"))

setMethod("Part", "missing", function(x, ...) {
    .Part()
})

setMethod("Part", "XMLInternalNode", function(x, ...) {
    attr<-xmlAttrs(x)
    var1 <- if (!is.na(attr["var1"])) attr["var1"] else vector()
    var2 <- if (!is.na(attr["var2"])) attr["var2"] else character()
    .Part(var1=var1, var2=var2, ...)
})

setMethod("Part", "ANY", function(x, var2, ...) {
    .Part(var1=x, var2=var2, ...)
})

如果需要,添加复制构造函数

setMethod("Part", "Part", function(x, ...) x$copy())

或者如果您自己的initialize方法执行了额外的操作并且符合默认initialize方法的合同(也充当复制构造函数),请使用

setMethod("Part", "Part", function(x, ...) .Part(x, ...))

将构造函数共享的任何公共代码添加到initialize方法,确保您的initialize方法充当复制构造函数,并在没有任何参数的情况下调用。

确保简单的测试用例正常工作

library(XML)
Part()
Part(TRUE, "var2")
txt <- "<doc> <part var2=\"abc\"/> </doc>"
node <- xmlTreeParse(txt, useInternalNodes = TRUE)[["//part"]]
p1 <- Part(node)
p2 <- Part(p1)
p1$var2 <- "xyz"
p2$var2            ## "abc"