This will create active bindings amongst the synonyms. To minimize copying, the first one that exists in the character vector will become the "canonical" object. All others named in the character vector will be activeBindings to that canonical one. This synonym list will be assigned to the envir, as an object named objectSynonyms. That object will have an attribute called, bindings indicating which one is the canonical one and which is/are the activeBindings. EXPERIMENTAL: If the objects are removed during a spades call by, say, a module, then at the end of the event, the spades call will replace the bindings. In other words, if a module deletes the object, it will "come back". This may not always be desired.

objectSynonyms(envir, synonyms)

Arguments

envir

An environment, which in the context of SpaDES.core is usually a simList to find and/or place the objectSynonyms object.

synonyms

A list of synonym character vectors, such as list(c("age", "ageMap", "age2"), c("veg", "vegMap"))

Value

Active bindings in the envir so that all synonyms point to the same canonical object, e.g., they would be at envir[[synonym[[1]][1]]] and envir[[synonym[[1]][2]]], if a list of length one is passed into synonyms, with a character vector of length two. See examples.

Details

This is very experimental and only has minimal tests. Please report if this is not working, and under what circumstances (e.g., please submit a reproducible example to our issues tracker)

This function will append any new objectSynonym to any pre-existing objectSynonym in the envir. Similarly, this function assumes transitivity, i.e., if age and ageMap are synonyms, and ageMap and timeSinceFire are synonyms, then age and timeSinceFire must be synonyms.

Examples

sim <- simInit()
#> Setting:
#>   options(
#>     reproducible.cachePath = '/tmp/Rtmp45trFG/myProject/cache'
#>     spades.inputPath = '/tmp/Rtmp45trFG/myProject/inputs'
#>     spades.outputPath = '/tmp/Rtmp45trFG/myProject/outputs'
#>     spades.modulePath = '/tmp/Rtmp45trFG/myProject/modules'
#>     spades.scratchPath = '/tmp/Rtmp45trFG/SpaDES/scratch'
#>   )
#> Nov21 04:22:42 simInit Using setDTthreads(1). To change: 'options(spades.DTthreads = X)'.
#> Elpsed time for simInit: 0.02783465 secs

sim$age <- 1:10;
sim <- objectSynonyms(sim, list(c("age", "ageMap")))

identical(sim$ageMap, sim$age)
#> [1] TRUE
sim$age <- 4
identical(sim$ageMap, sim$age)
#> [1] TRUE
sim$ageMap <- 2:5
sim$ageMap[3] <- 11
identical(sim$ageMap, sim$age)
#> [1] TRUE

# Also works to pass it in as an object
objectSynonyms <- list(c("age", "ageMap"))
sim <- simInit(objects = list(objectSynonyms = objectSynonyms))
#> Setting:
#>   options(
#>     reproducible.cachePath = '/tmp/Rtmp45trFG/myProject/cache'
#>     spades.inputPath = '/tmp/Rtmp45trFG/myProject/inputs'
#>     spades.outputPath = '/tmp/Rtmp45trFG/myProject/outputs'
#>     spades.modulePath = '/tmp/Rtmp45trFG/myProject/modules'
#>     spades.scratchPath = '/tmp/Rtmp45trFG/SpaDES/scratch'
#>   )
#> Nov21 04:22:42 simInit Using setDTthreads(1). To change: 'options(spades.DTthreads = X)'.
#> Elpsed time for simInit: 0.03136134 secs
identical(sim$ageMap, sim$age) # they are NULL at this point
#> [1] TRUE
sim$age <- 1:10
identical(sim$ageMap, sim$age) # they are not NULL at this point
#> [1] TRUE

## More complicated, with 'updating' i.e., you can add new synonyms to previous
sim <- simInit()
#> Setting:
#>   options(
#>     reproducible.cachePath = '/tmp/Rtmp45trFG/myProject/cache'
#>     spades.inputPath = '/tmp/Rtmp45trFG/myProject/inputs'
#>     spades.outputPath = '/tmp/Rtmp45trFG/myProject/outputs'
#>     spades.modulePath = '/tmp/Rtmp45trFG/myProject/modules'
#>     spades.scratchPath = '/tmp/Rtmp45trFG/SpaDES/scratch'
#>   )
#> Nov21 04:22:42 simInit Using setDTthreads(1). To change: 'options(spades.DTthreads = X)'.
#> Elpsed time for simInit: 0.02790022 secs
os <- list(c("age", "ageMap"), c("vegMap", "veg"), c("studyArea", "studyArea2"))
os2 <- list(c("ageMap", "timeSinceFire", "tsf"),
            c("systime", "systime2"),
            c("vegMap", "veg"))
sim <- objectSynonyms(sim, os)
sim <- objectSynonyms(sim, os2)
#> age, ageMap already exist; using the first one, age
#> vegMap, veg already exist; using the first one, vegMap

# check
sim$objectSynonyms
#> [[1]]
#> [1] "studyArea"  "studyArea2"
#> 
#> [[2]]
#> [1] "age"           "ageMap"        "timeSinceFire" "tsf"          
#> 
#> [[3]]
#> [1] "systime"  "systime2"
#> 
#> [[4]]
#> [1] "vegMap" "veg"   
#> 
#> attr(,"bindings")
#> attr(,"bindings")[[1]]
#> attr(,"bindings")[[1]]$canonicalVersion
#> [1] "studyArea"
#> 
#> attr(,"bindings")[[1]]$activeBindingObjects
#> [1] "studyArea2"
#> 
#> 
#> attr(,"bindings")[[2]]
#> attr(,"bindings")[[2]]$canonicalVersion
#> [1] "age"
#> 
#> attr(,"bindings")[[2]]$activeBindingObjects
#> [1] "ageMap"        "timeSinceFire" "tsf"          
#> 
#> 
#> attr(,"bindings")[[3]]
#> attr(,"bindings")[[3]]$canonicalVersion
#> [1] "systime"
#> 
#> attr(,"bindings")[[3]]$activeBindingObjects
#> [1] "systime2"
#> 
#> 
#> attr(,"bindings")[[4]]
#> attr(,"bindings")[[4]]$canonicalVersion
#> [1] "vegMap"
#> 
#> attr(,"bindings")[[4]]$activeBindingObjects
#> [1] "veg"
#> 
#>