Skip to content

Instantly share code, notes, and snippets.

@jmbarbone
Last active February 3, 2023 22:45
Show Gist options
  • Save jmbarbone/6de58e6e35bbc1c7bdb300b71982c36f to your computer and use it in GitHub Desktop.
Save jmbarbone/6de58e6e35bbc1c7bdb300b71982c36f to your computer and use it in GitHub Desktop.
"private" methods in ReferenceClass objects
fooReferenceClass <- setRefClass(
  "fooReferenceClass",
  fields = list(
    private = "environment",
    n = "integer"
  )
)

# create a list of values that will be transfered to private.  alternatively,
# just assign these in list and ther env will be taken care of
foo_ls <- list(
  foo = function() {
    # add 1 to n, subtract 1 from m
    .self$n <- .self$n + 1L
    private$m <- private$m - 1L
    .self
  },
  m = 0L
)

fooReferenceClass$methods(
  initialize = function() {
    # create new environment
    env <- new.env()
    # reassign the environment of all the functions
    foo_ls <- lapply(foo_ls, function(i) {
      if (is.function(i)) {
        environment(i) <- env
      }
      i
    })
    # send the list to the new env
    list2env(foo_ls, env)
    
    # # alternatively, if defined within initialize:
    # env <- list2env(
    #   list(
    #     foo = function() {
    #       # add 1 to n, subtract 1 from m
    #       .self$n <- .self$n + 1L
    #       private$m <- private$m - 1L
    #       .self
    #     },
    #     m = 0L
    #   ),
    #   environment()
    # )
    # # however, you may get a warning about local assignment of private$m.  This
    # # doesn't seem to matter, but it is annoying
    
    .self$private <- env
    .self$n <- 0L
    .self
  },
  
  show = function() {
    writeLines(sprintf("n = %i, m = %i", n, private$m))
  },
  
  increase = function() {
    # calls the "private" environment
    private$foo()
  }
)

foo <- fooReferenceClass$new()
foo$show()
#> n = 0, m = 0
foo$private$foo()
#> n = 1, m = -1
foo$private$foo()
#> n = 2, m = -2
foo$private$foo()
#> n = 3, m = -3

Created on 2023-02-03 with reprex v2.0.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment