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"
精彩评论