Одновременное обновление объекта и возвращение значения в классах S4 - PullRequest
0 голосов
/ 25 марта 2011

Мне нужно написать один метод, который одновременно обновляет объект и возвращает значение. Я хочу знать, есть ли способ сделать это в классах S4. Контекстом этого является то, что я пытаюсь написать класс S4 для генерации списка, к каждому элементу которого можно получить доступ, только если известен закрытый ключ. Для этого мне нужен метод getNewSlot, который одновременно обновляет длину списка и списка ключей и возвращает пару ключей индекса. Код указан ниже:

setClass("ProtectedRObjectList", 
  representation(objectList = "list", keys = "character", length = "numeric"))

setGeneric(
  name = "getNewSlot",
  def = function(object,value){standardGeneric("getNewSlot")})

setMethod(
  f = "getNewSlot", 
  signature = "ProtectedRObjectList", 
  definition = function(object){
    if(length(object@length)==0)
    {
      #initial case
      object@length <- 0;
    }

    #update list length and generate random key
    object@length<-object@length + 1;
    object@keys[object@length]<-paste(sample(c(letters, LETTERS), 15, replace =TRUE), collapse = "");
    #return "index, key" pair
    return(list("index" = object@length, "key" = object@keys[object@length]))
  }
)

Вот результат этого метода. Как видите, код возвращает нужную пару «индекс, ключ», но не обновляет объект.

> thisObj<-new("ProtectedRObjectList")
> thisObj
An object of class "ProtectedRObjectList"
Slot "objectList":
list()

Slot "keys":
character(0)

Slot "length":
numeric(0)

> output<-getNewSlot(thisObj)
> output
$index
[1] 1

$key
[1] "cjdkDvAaNjvVKdw"

> thisObj
An object of class "ProtectedRObjectList"
Slot "objectList":
list()

Slot "keys":
character(0)

Slot "length":
numeric(0)

1 Ответ

2 голосов
/ 26 марта 2011

возможно, это не то, что вам нужно, но, вероятно, класс R5 подходит для ваших целей, так как вам нужен вызов функции передачи по ссылке.

легко переписать класс R5 из класса S4 (и реализациюв R5 проще, чем в S4).Вот определение (обратите внимание, что поле length заменено на len из-за дублирования имени):

ProtectedRObjectList <- setRefClass(
  "ProtectedRObjectList", 
  fields = list(objectList = "list", keys = "character", len = "numeric"),
  methods=list(
    getNewSlot = function(){
      if(length(len)==0)
      {
        #initial case
        len <<- 0;
      }
      #update list length and generate random key
      len<<-len + 1;
      keys[len]<<-paste(sample(c(letters, LETTERS), 15, replace =TRUE), collapse = "");
      #return "index, key" pair
      return(list("index" = len, "key" = keys[len]))
    }
  )
)

и использование:

> thisObj<-ProtectedRObjectList$new()
> thisObj
An object of class "ProtectedRObjectList"
<environment: 0x116207c30>
> thisObj$len
numeric(0)
> thisObj$keys
character(0)
> 
> output<-thisObj$getNewSlot()
> output
$index
[1] 1

$key
[1] "GeCyCTdIflcYFbE"

> 
> thisObj$len
[1] 1
> thisObj$keys
[1] "GeCyCTdIflcYFbE"
...