#------------------------------------------------------------------------------- # CLASS DEF #------------------------------------------------------------------------------- Shabubu <- setRefClass( Class="Shabubu", fields=list( BUFFER="environment", HISTORY="environment", DYNCNTRL="environment", main="data.frame" ), methods=list( # GENERIC GENERATOR=function() getRefClass("Shabubu"), fields=function() GENERATOR()$fields(), methods=function() GENERATOR()$methods(), # accessors=function() GENERATOR()$accessors, # / # DATA RETRIEVAL data.retrieve=function() data.retrieve.core(.self=.self), # / # BUFFER buffer.refresh=function() assign("main", data.retrieve(), envir=BUFFER), buffer.clean=function() rm(list=ls(BUFFER, all.names=TRUE), envir=BUFFER), # / # DYNCNTRL dyncntrl.set=function(field, arg, val) { if(!exists(field, DYNCNTRL)) assign(field, new.env(parent=emptyenv()), DYNCNTRL) assign(arg, val, get(field, DYNCNTRL)) cat(paste("Setting '", arg, "=", val, "' for field '", field, "'.", sep=""), sep="\n") }, dyncntrl.get=function(field, arg) { if(!exists(field, DYNCNTRL)) return(NULL) if(!exists(arg, get(field, DYNCNTRL))) return(NULL) get(arg, get(field, DYNCNTRL)) }, # / # STATIC static.clean=function(field) { expr <- paste("cls <- class(", field, ")", sep="") eval(parse(text=expr)) expr.val <- paste("as.", cls, "(NULL)", sep="") expr <- paste(field, " <<- ", expr.val, sep="") eval(parse(text=expr)) cat(paste("Removing values for field '", field, "' (STATIC).", sep=""), sep="\n") }, # / # GET main.get=function( do.static=dyncntrl.get(field="main", arg="do.static"), do.buffer.clean=dyncntrl.get(field="main", arg="do.buffer.clean") ) { if(is.null(do.static)) { dyncntrl.set(field="main", arg="do.static", val=TRUE) do.static <- dyncntrl.get(field="main", arg="do.static") } if(is.null(do.buffer.clean)) { dyncntrl.set(field="main", arg="do.buffer.clean", val=FALSE) do.buffer.clean <- dyncntrl.get(field="main", arg="do.buffer.clean") } if(do.static) { cat("Field 'main' (STATIC).", sep="\n") if(!length(main)) { cat("Initializing ...", sep="\n") main <<- main.get(do.static=FALSE, do.buffer.clean=TRUE) } rtn <- main } else { cat("Field 'main' (DYNAMIC).", sep="\n") # REFRESH BUFFER buffer.refresh() # / rtn <- BUFFER$main if(do.buffer.clean) { cat("Cleaning BUFFER.", sep="\n") buffer.clean() } } return(rtn) }, # / # SET main.set=function( val, do.update.remote=dyncntrl.get(field="main", arg="do.update.remote") ) { if(is.null(do.update.remote)) { dyncntrl.set(field="main", arg="do.update.remote", val=FALSE) do.update.remote <- dyncntrl.get(field="main", arg="do.update.remote") } cat("Setting value for field 'main' (STATIC).", sep="\n") main <<- val if(do.update.remote) { cat("Updating remote data linked to field 'main'.", sep="\n") BUFFER$main <<- val data.writeback.core(.self=.self, val=val) } } # / ) ) # /CLASS DEF ----- #------------------------------------------------------------------------------- # GENERICS #------------------------------------------------------------------------------- setGeneric(name="data.retrieve.core", def=function(.self, ...){standardGeneric("data.retrieve.core")}, signature=c(".self") ) setGeneric(name="data.writeback.core", def=function(.self, val, ...){standardGeneric("data.writeback.core")}, signature=c(".self") ) # /GENERICS ----- #------------------------------------------------------------------------------- # METHODS #------------------------------------------------------------------------------- setMethod( f="data.retrieve.core", signature=signature("Shabubu"), definition=function(.self, ...) { cat("THIS IS THE METHOD FOR 'SHABUBU'.", sep="\n") rtn <- DB$Shabubu return(rtn) } ) setMethod( f="data.writeback.core", signature=signature("Shabubu"), definition=function(.self, val, ...) { cat("THIS IS THE METHOD FOR 'SHABUBU'.", sep="\n") DB$Shabubu <- val return(TRUE) } ) # /METHODS ----- #------------------------------------------------------------------------------- # EXAMPLE #------------------------------------------------------------------------------- # Environment as database imitation (remote location): DB <- new.env(parent=emptyenv()) DB$Shabubu <- data.frame(a=1:10, b=letters[1:10]) DB$Shabubu # Instance init: shabubu <- Shabubu$new() shabubu$GENERATOR() shabubu$fields() shabubu$methods() shabubu$main # Get dynamical value for 'main' (as default for 'do.static=FALSE'): shabubu$main.get() # In case I'd wanted static values before dynamic values were ever retrieved, # the method automatically takes care of initialization. ls(shabubu$BUFFER) # BUFFER was cleaned right after dynamic retrieval because default for # do.buffer.clean=TRUE shabubu$main # Get static value for 'main' via explicitly setting 'do.static': shabubu$main.get(do.static=TRUE) # Get dynamic value for 'main' without cleaning buffer afterwards: shabubu$main.get(do.static=FALSE, do.buffer.clean=FALSE) ls(shabubu$BUFFER) shabubu$BUFFER$main # Inspect method defaults: shabubu$dyncntrl.get(field="main", arg="do.static") shabubu$dyncntrl.get(field="main", arg="do.buffer.clean") shabubu$dyncntrl.get(field="main", arg="do.update.clean") # Change defaults: shabubu$dyncntrl.set(field="main", arg="do.static", val=TRUE) shabubu$dyncntrl.set(field="main", arg="do.buffer.clean", val=FALSE) shabubu$dyncntrl.set(field="main", arg="do.update.clean", val=FALSE) # As default was changed, this now calls the static value: shabubu$main.get() shabubu$main.set(val=shabubu$main[1:5,]) shabubu$main # Values changed shabubu$main.get() shabubu$main.get(do.static=FALSE) shabubu$main.set(val=shabubu$main.get(do.static=FALSE)) shabubu$main shabubu$main.set(val=shabubu$main[1:5,], do.update.remote=TRUE) DB$Shabubu # Values in DB changed # Cleaning fields: shabubu$static.clean(field="main") shabubu$main # Values gone # /EXAMPLE