开发者

Simultaneously updating object and returning value in S4 classes

开发者 https://www.devze.com 2023-02-20 09:04 出处:网络
I need to write one method that simultaneously updates an object and returns a value.I want to know if there is a way to do this in S4 classes.The context for this is that I am trying to write an S4 c

I need to write one method that simultaneously updates an object and returns a value. I want to know if there is a way to do this in S4 classes. The context for this is that I am trying to write an S4 class to generate a list each element of which can be accessed only if a private key is known. To do this I need a method getNewSlot that simultaneously updates the length of the list and the key list and returns the index key pair. The code is provided below:

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]))
  }
)

Here is the output of this method. As you can see, the code returns the desired "index, key" pair, but doesn't update the object.

> 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"

> thisO开发者_如何学编程bj
An object of class "ProtectedRObjectList"
Slot "objectList":
list()

Slot "keys":
character(0)

Slot "length":
numeric(0)


maybe this is not what you want, but probably R5 class is suitable for your purpose since you need pass-by-reference function call.

it is easy to rewrite R5 class from S4 class (and implementation in R5 is easier than that in S4).
Here is a definition (note that field length is replaced by len because of name duplication):

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]))
    }
  )
)

and usage:

> 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"
0

精彩评论

暂无评论...
验证码 换一张
取 消