The short answer - based on Hadley's comments above - is no. R's reference classes do not have static variables.
r reference classes - do they have static field members/variables?
-
28-11-2021 - |
Question
I have been playing a little with R's R5 class system to see what it can and can't do. In that process I have stumbled upon what looks like static class field members (which does not appear to be in the documentation - but i could have missed it)
[2014 update]
Warning !!! : The following code does not work with R version >= 3.0
This post, its answers and particularly the comments provide useful insights and reminders about the R5 OO-system and the R language in general. However it is probably a bad idea to cultivate the idiom of using the environment of the R5 class instances directly.
[end 2014 update]
In the following code, the first field is the classic definition of an instance field variable. The second definition appears to create a static class field using an accessor method. I would like to know if this use is kosher (or is my code example simply coincidental). The third field use creates a quasi-private instant field variable using an accessor method.
assertClass <- function(x, className, R5check=FALSE) {
# simple utility function
stopifnot(class(x)[1] == className)
if(R5check) stopifnot(is(x, 'envRefClass'))
}
A <- setRefClass('A',
fields = list(
# 1. public, typed, instance field
myPublicInstanceVar = 'character',
# 2. this assignment appears static
# but if the field me.static.private
# was declared in the field list
# it would be a local instance var
myPrivateStaticVar = function(x) {
if (!missing(x)) {
assertClass(x, 'character')
me.static.private <<- x
}
me.static.private
},
# 3. quasi-private, typed, instance field
myPrivateInstanceVar = function(x) {
if (!missing(x)) {
assertClass(x, 'character')
.self$me.private <<- x
}
.self$me.private
}
),
methods = list(
initialize = function (c='default') {
myPublicInstanceVar <<- c
myPrivateStaticVar <<- c
myPrivateInstanceVar <<- c
}
)
)
# test instantiation
instance1.of.A <- A$new('first instance')
str(instance1.of.A)
instance2.of.A <- A$new('second instance')
str(instance1.of.A)
str(instance2.of.A)
instance3.of.A <- getRefClass('A')$new('third instance')
instance3.of.A$myPrivateStaticVar <- 'Third instance - changed'
print(instance1.of.A$myPrivateStaticVar)
print(instance2.of.A$myPrivateStaticVar)
print(instance3.of.A$myPrivateStaticVar)
str(instance1.of.A)
str(instance2.of.A)
str(instance3.of.A)
# but not really private ...
instance1.of.A$myPublicInstanceVar # works
instance1.of.A$me.static.private # DOES NOT WORK - where is this variable stored
instance1.of.A$me.private # works
# till death do us part
instance3.of.A <- NULL
gc()
str(instance1.of.A)
str(instance2.of.A)
str(instance3.of.A)
If you run this code - you can see that the second field variable appears to operate as a static class member. What is less clear to me is where the reference class keeps this field (hence my comment in the penultimate line above).
Solution