setOrRetrieve: Set or retrieve a jaspObject

%setOrRetrieve%R Documentation

Set or retrieve a jaspObject

Description

⁠%setOrRetrieve%⁠ is a useful shorthand for a common pattern.

isRecomputed tests if a jaspObject was recomputed or not, if it was created with %setOrRetrieve%.

Usage

lhs %setOrRetrieve% rhs

isRecomputed(x)

Arguments

lhs

an assignment into a jaspObject, e.g., container[["table"]].

rhs

a function call that creates a jaspObject.

x

a jaspObject, or missing in which case the last created or retrieved jaspObject is considered.

Details

⁠%setOrRetrieve%⁠ exists as a shorthand for the following very common pattern:

if (is.null(jaspContainer[[key]])) { # was this subelement already computed?
  subContainer <- createJaspContainer(..., dependencies = ...) # no, so recreate it
  jaspContainer[[key]] <- subContainer # store it with this key
} else {
  subContainer <- jaspContainer[[key]] # it was recomputed, retrieve it from the state.
}

The code above duplicates the phrase jaspContainer[[key]] quite a bit. When this is a string literal, this introduces a lot of room for copy-paste errors. with ⁠%setOrRetrieve%⁠, this becomes

subContainer <- jaspContainer[[key]] \%setOrRetrieve\% createJaspContainer(..., dependencies = ...)

The same pattern can also be used to set and retrieve state objects. Consider the following code

if (is.null(jaspContainer[[key]])) {
  object <- expensiveComputeFunction()
  state <- createJaspState(object, dependencies = ...)
  jaspContainer[[key]] <- state
} else {
  object <- jaspContainer[[key]]$object
}

with ⁠%setOrRetrieve%⁠, this becomes

object <- jaspContainer[[key]] \%setOrRetrieve\% (
  expensiveComputeFunction() |>
  createJaspState(dependencies = ...)
)

If the rhs passed to ⁠%setOrRetrieve%⁠ returns an object of class jaspStateR then ⁠%setOrRetrieve%⁠ returns the object it contains, rather than the jaspObject itself. In all other cases the jaspObject is returned. If the rhs does not return a jaspObject, an error is thrown.

isRecomputed only works when %setOrRetrieve% is used to set or retrieve a jaspObject.

Examples

library(jaspBase)

# otherwise jaspState crashes badly (should be fixed another time)
jaspResultsCPP        <- jaspBase:::loadJaspResults("a name")
jaspResultsCPP$title  <- "a title"
jaspResults           <- jaspBase:::jaspResultsR$new(jaspResultsCPP)

ctr <- createJaspContainer("ctr1")

result <- ctr[["ctr2"]] %setOrRetrieve%
  createJaspContainer("my name")

result               # the container
isRecomputed(result) # true
isRecomputed()       # true

# the same statement as before
result <- ctr[["ctr2"]] %setOrRetrieve%
  createJaspContainer("my name")

isRecomputed(result) # false
isRecomputed()       # false

set.seed(123)
computeFunction <- function() {
  print("working hard!")
  c(a = rnorm(1))
}

result <- ctr[["state"]] %setOrRetrieve% (
  computeFunction() |>
    createJaspState()
)

result                         # the random number
#\dontrun{isRecomputed(result)} # intentional error
#This is a nice intentional error but renv keeps messing up my builds because of this.
isRecomputed(ctr[["state"]])   # true
isRecomputed()                 # true

result2 <- ctr[["state"]] %setOrRetrieve% (
  computeFunction() |>
    createJaspState()
)

identical(result, result2)   # the random number is identical, so retrieved from the state
isRecomputed(ctr[["state"]]) # false
isRecomputed()               # false

# Note that only works when the left hand side indexes inside a jaspObject
a <- 1
#\dontrun{a %setOrRetrieve% 2} # intentional error

jasp-stats/jaspBase documentation built on April 5, 2025, 3:46 p.m.