futile.options/0000755000176200001440000000000013266461734013250 5ustar liggesusersfutile.options/NAMESPACE0000644000176200001440000000024013266410214014446 0ustar liggesusersexportPattern("^[^\\.]") S3method(resetOptions, default) S3method(resetOptions, character) S3method(updateOptions, default) S3method(updateOptions, character) futile.options/R/0000755000176200001440000000000013266410214013434 5ustar liggesusersfutile.options/R/options.R0000644000176200001440000000530413266410214015254 0ustar liggesusers# Passing the update argument to the resulting options manager will update # the provided keys and values. Note that update[[1]] are the keys and # update[[2]] are the values. # Examples of using options.manager # log.options <- options.manager('log.options', defaults=list(logger='ROOT')) # log.options(a=123, b=6234) # log.options() # log.options(a=123, b=6234) # resetOptions(log.options, c=29) # log.options() # Generates a function to retrieve options for a given name OptionsManager <- function(option.name, defaults=list()) { # Define a function to update options up <- function(os) { my.options <- list() my.options[[option.name]] <- os options(my.options) } up(list()) function(..., simplify=FALSE, update=list()) { os <- getOption(option.name) if (length(os) < 1) { os <- defaults up(os) } args <- list(...) if (length(update) > 0) invisible(updateOptions(option.name, update[[1]], update[[2]])) if (length(args) == 0) return(os) # Getter if (any(is.null(names(args)))) { ns <- sapply(args, '[') ns <- ns[ns %in% names(os)] if (length(ns) == 0) return(NULL) if (length(ns) == 1) return(os[[ns]]) return(sapply(os[ns], '[', simplify=simplify)) } # Setter for (x in names(args)) os[[x]] <- args[[x]] up(os) invisible() } } # Reset options for a given option set resetOptions <- function(option.name, ...) UseMethod('resetOptions') resetOptions.default <- function(option.name, ...) resetOptions.character(deparse(substitute(option.name)), ...) resetOptions.character <- function(option.name, ...) { my.options <- list() my.options[[option.name]] <- NA options(my.options) args <- list(...) if (length(args) > 0) { ks <- names(args) vs <- sapply(args, '[') kvs <- paste(ks,vs, sep='=') line <- paste(kvs, collapse=',') exp <- parse(text=paste('new.options <- ',option.name,'(',line,')',sep='')) eval(exp) } invisible() } # Update a specific option in an option set (a generated function) # This is primarily used when dynamic creation of options variables are needed. updateOptions <- function(option.name, ...) UseMethod('updateOptions') updateOptions.default <- function(option.name, ...) updateOptions.character(deparse(substitute(option.name)), ...) updateOptions.character <- function(option.name, key, value, ...) { os <- getOption(option.name) if (is.null(os)) stop(paste("Cannot update non-existent options:",option.name)) if (length(key) == 1) os[[key]] <- value else for (idx in 1:length(key)) os[[key[idx]]] <- value[idx] my.options <- list() my.options[[option.name]] <- os options(my.options) invisible() } futile.options/R/deprecated.R0000644000176200001440000000040713266410214015660 0ustar liggesusers# This is here for backwards compatibility options.manager <- function(option.name, defaults=NULL) { OptionsManager(option.name, defaults) } # This is here for backwards compatibility reset.options <- function(option.name, ...) resetOptions(option.name, ...) futile.options/README.md0000644000176200001440000000225613266410214014517 0ustar liggesusersThe ’futile.options’ subsystem provides an easy user-defined options management system that is properly scoped. This means that options created via ’futile.options’ are fully self-contained and will not collide with options defined in other packages. This package is a self-contained package within the futile suite of libraries. Details ======= While R provides a useful mechanism for storing and retrieving options, there is a danger that variable names collide with names defined by a package that a user’s code depends. These types of errors are difficult to detect and should be avoided. Using ’futile.options’ addresses this problem by properly scoping variables within its own custom ’namespace’. This is handled by the ’OptionsManager’, which acts as a generator for functions that manage user- defined options. An added benefit to the package is that default values are automatically supported in the creation of the bespoke options manager. Example ======= my.options <- OptionsManager('my.options', default=list(a=2,b=3)) my.options(c=4,d='hello') my.options(c('b','d')) reset.options(my.options) my.options('c') Author ====== Brian Lee Yung Rowe futile.options/MD50000644000176200001440000000053513266461734013563 0ustar liggesusersaae261f50d195ac5caf5949e7557cd7f *DESCRIPTION d93afeaf768fc32fbdf4c08a2ee5e101 *NAMESPACE 5e59f77aa3f4b4eddc7a81158354720f *R/deprecated.R 3e1344aff6bba71d444c9058f5392b33 *R/options.R e81292835413a9bcf408ad451ec5e4e5 *README.md 300ef9ec93b8bae62dbc52d286c219fb *man/OptionsManager.Rd 80bc2a0543fda563869732fe2412cd17 *man/futile.options-package.Rd futile.options/DESCRIPTION0000644000176200001440000000065513266461734014764 0ustar liggesusersPackage: futile.options Type: Package Title: Futile Options Management Version: 1.0.1 Date: 2018-04-20 Author: Brian Lee Yung Rowe Maintainer: Brian Lee Yung Rowe Depends: R (>= 2.8.0) Description: A scoped options management framework. Used in other packages. License: LGPL-3 LazyLoad: yes NeedsCompilation: no Packaged: 2018-04-20 16:08:58 UTC; brian Repository: CRAN Date/Publication: 2018-04-20 22:04:12 UTC futile.options/man/0000755000176200001440000000000013266410214014006 5ustar liggesusersfutile.options/man/futile.options-package.Rd0000644000176200001440000000273713266410214020661 0ustar liggesusers\name{futile.options-package} \alias{futile.options-package} \alias{futile.options} \docType{package} \title{ A scoped options management framework } \description{ The 'futile.options' subsystem provides an easy user-defined options management system that is properly scoped. This means that options created via 'futile.options' are fully self-contained and will not collide with options defined in other packages. } \details{ \tabular{ll}{ Package: \tab futile.options\cr Type: \tab Package\cr Version: \tab 1.0.1\cr Date: \tab 2018-04-20\cr License: \tab LGPL-3\cr LazyLoad: \tab yes\cr } While R provides a useful mechanism for storing and retrieving options, there is a danger that variable names collide with names defined by a package that a user's code depends. These types of errors are difficult to detect and should be avoided. Using 'futile.options' addresses this problem by properly scoping variables within its own custom 'namespace'. This is handled by the 'OptionsManager', which acts as a generator for functions that manage user- defined options. An added benefit to the package is that default values are automatically supported in the creation of the bespoke options manager. } \author{ Brian Lee Yung Rowe } \keyword{ package } \keyword{ attribute } \keyword{ logic } \seealso{ \code{\link{OptionsManager}} } \examples{ my.options <- OptionsManager('my.options', defaults=list(a=1,b=2)) my.options(a=5, c=3) my.options('a') } futile.options/man/OptionsManager.Rd0000644000176200001440000000672713266410214017237 0ustar liggesusers\name{OptionsManager} \alias{OptionsManager} \alias{resetOptions} \alias{resetOptions.default} \alias{resetOptions.character} \alias{updateOptions} \alias{updateOptions.default} \alias{updateOptions.character} \alias{options.manager} \alias{reset.options} \title{ Futile options management } \description{ Included as part of futile is an options subsystem that facilitates the management of options for a particular application. The options.manager function produces a scoped options set within the environment, to protect against collisions with other libraries or applications. The options subsystem also provides default settings that can be restored by calling reset.options. } \usage{ OptionsManager(option.name, defaults = list()) \method{resetOptions}{default}(option.name, ...) \method{resetOptions}{character}(option.name, ...) \method{updateOptions}{default}(option.name, ...) \method{updateOptions}{character}(option.name, key, value, ...) options.manager(option.name, defaults = NULL) reset.options(option.name, ...) } \arguments{ \item{option.name}{ The namespace of the options set } \item{defaults}{ A list of default values to use for the new options manager } \item{key}{ A vector of keys in the options that need to be updated } \item{value}{ A vector of values that correspond to the keys above } \item{\dots}{ Option values to set after resetting } } \details{ Using the options subsystem is simple. The first step is to create a specific options manager for a given namespace by using the 'OptionsManager' function. It is possible to specify some default values by passing a list to the default argument. This function returns a specialized function for managing options in the given namespace. With the new function, options can be set and accessed in an isolated namespace. The options can also be reset using 'resetOptions' to the default values. Note that if multiple values are accessed, to support lists and other complex data structures, the output is a list. If a vector is preferred, pass simplify=TRUE as an argument to the user-defined options management function. Another arugment available in the resulting function is 'update', which allows specific values to be updated dynamically rather than via named key=value pairs. This is useful in certain situations but can be safely ignored for most situations. To reset options back to default settings, use the 'reset.options' function. In certain cases, stored options may need to be set programattically, i.e. their name is constructed dynamically. When this occurs, use update.options to set the values. NOTE: The functions 'options.manager' and 'reset.options' are deprecated but still extant to maintain backwards compatibility. All futile libraries are renamed to avoid naming collisions with S3 generics. Furthermore, any futile function that returns a function will be PascalCased, whereas all others will be camelCased. The dot notation is reserved strictly for S3 generics. } \value{ The 'OptionsManager' function produces a custom function to manage options for the specified namespace. Use this function to access and set options in your code. } \author{ Brian Lee Yung Rowe } \examples{ my.options <- OptionsManager('my.options', default=list(a=2,b=3)) my.options(c=4,d='hello') my.options('b') my.options('c') resetOptions(my.options) my.options('c') updateOptions(my.options, paste('key',1,sep='.'), 10) my.options('key.1') } \keyword{ array }