2013-09-20 5 views
1

Мне нравится изменять исходный src таким образом, чтобы функция инициализации выглядела как определенные contructors. Я хотел бы изменить на следующий примерСправочные классы конструктора

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 
    } 

Помимо как обрабатывать значение по умолчанию для типа ЛЮБЫХ? До сих пор я использую vector().

ответ

1

Не записывайте метод 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" 
+0

Многие ТНХ, это излишним, чтобы объединить его с помощью метода инициализации в folowing пути к? ' generic.initialize <-функция (...) { args <- list (...); map <- .self $ getRefClass() $ fields(); map <- map [map! = "ANY"]; idx <- names (args)% in% names (map); args [idx] <- Map (as, args [idx], map [names (args) [idx]]); do.call (.self $ initFields, args); callSuper (...); } .Part <- setRefClass (Class = "Part", fields = c (var0 = "ANY", var1 = "numeric", var2 = "character"), methods = list (initialize = generic.initialize)) setMethod («Part», «XMLInternalNode», function (x, ...) { attr <-xmlAttrs (x); do.call (.Part, as.list (attr)); }) ' – Klaus

+0

Проблема который поставляется вместе с этим оператором, заключается в том, что я не могу использовать функцию-член вызова (.self $ foo) в конструкторе. Как я могу справиться с этим? – Klaus

+0

Как создать копию объекта? setMethod («Part», «Part», function (x, ...) {.Part (var1 = x $ var1, var2 = x $ var2, ...)}), или я должен использовать 'x $ copy() '? – Klaus