Skip to content

Repository files navigation

extendedRef - Extended Reference Classes

Build Statuscodecov.iolifecycle

The goal of staticRef is to add static and private variable and methods support for R reference classes.

Installation

You can install the released version of extendedRef from CRAN with:

install.packages("extendedRef")

Example

To setup an extended reference class use the setExtendedRefClass() function. For this example we will create a registered counter class that tracks all the counters created and the individual counts.

counter<- setExtendedRefClass('registeredCounter',
# fields define the publicly accessible fields, same as setRefClassfields= c(name='character'),
# private are the variables that are not accessible via the `$` operatorprivate= c(count='integer'),
# staic specifies static variables common to all variables.static= c( counters='list' ),
# static.const specifies constants for the class that cannot be changed.# since these do not change they are specified once by a list with the # values they should take.static.const=list( max=3L),
# for illustration, we are artificially setting a maximum of 3 counters # Methods are specified with lists of functions.# static methodsstatic.methods=list( how_many_counters=function()length(counters)
, add_counter=function(counter){
x<-list(counter)
names(x) <-counter$namecounters<<- c(counters, x)
}),
# private methodsprivate.methods=list(private_initialize=function(){
# The public initialize, cannot use or alter private variables,# the `private_initialize` function serves this role. count<<-0L# The private initialize can also access the static variables,if (how_many_counters() <max) add_counter(.self) else
stop("Cannot create another counter!")
}),
# methods as with setRefClass defines the public methods.methods=list( increment=function()count<<-count+1L
, get_count=function()count
)
# note that the public function alters a 'private' variable.
)

This class may not be very useful but illustrates the concepts.

As before the counter object is a object generator function that creates objects from the exteneded reference class 'registeredCounter'. However, the generator object also provides a method for accessing the static variables and methods.

counter$static$how_many_counters()
#> [1] 0counter$static$max#> [1] 3
first<- counter(name='first')

We now have first as a counter and we have one counter registered.

first$get_count()
#> [1] 0counter$static$how_many_counters()
#> [1] 1

Counter is a reference class so you can do all the things that you would do with a reference class

first$increment()
first$get_count()
#> [1] 1
also.first<-firstalso.first$get_count()
#> [1] 1

Note that one thing you cannot do is access the private variable count.

first$count#> Error in envRefInferField(x, what, getClass(class(x)), selfEnv): 'count' is not a valid field or method name for reference class "registeredCounter"

For the static variables all object have access to them from their internal methods, but not publicly.

first$how_many_counters()
#> Error in envRefInferField(x, what, getClass(class(x)), selfEnv): 'how_many_counters' is not a valid field or method name for reference class "registeredCounter"

Let's create a few more counters.

second<- counter(name='second')
third<- counter(name='third')
fourth<- counter(name='fourth')
#> Error in private.methods$private_initialize(): Cannot create another counter!

We cannot add the fourth counter because we specified that we can only have 3 total.

counter$static$how_many_counters()
#> [1] 3

Since the counters are registered we can retrieve them from the registry.

counter$static$counters[['first']]$get_count()
#> [1] 1

The static variables are tied to the stored definition so there is always only one copy.

validate_that(identical(counter$def, getClass('registeredCounter')))
#> [1] TRUE

About

Extensions to the reference class system

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages