R6 icon indicating copy to clipboard operation
R6 copied to clipboard

Guidance on declaration and default values of a field

Open jennybc opened this issue 5 years ago • 1 comments

Summarizing a conversation in Slack.

Consider this snippet from the vignette:

library(R6)

Person <- R6Class("Person",
  public = list(
    name = NULL,
    hair = NULL,
    initialize = function(name = NA, hair = NA) {
      self$name <- name
      self$hair <- hair
      self$greet()
    },
    set_hair = function(val) {
      self$hair <- val
    },
    greet = function() {
      cat(paste0("Hello, my name is ", self$name, ".\n"))
    }
  )
)

Nitpick: the default NA values should probably be NA_character_ to signal the expected type.

How do you decide to set name and hair to NULL when declared in the public list and then set NA as the default value in $initialize()?

After much discussion, we reached a few conclusions re: a basic workflow, when there's no specific reason to do otherwise:

  • If $initialize() exists, declare the fact that a field will exist via foo = NULL and handle everything else (such as default values) via $initialize(). Don't spread knowledge and logic over both places.
  • If the default value involves a call to another package, you generally want that to happen when an R6 object is created, not at the time of R CMD INSTALL. So doing this in the declaration placeholder is a bad design, unless the R6Class() call is inside a function, which is rare. This underscores the wisdom of using NULL in the placeholder and putting default logic in the initializer.

cc and thanks @gaborcsardi @hadley

jennybc avatar Nov 15 '18 22:11 jennybc

Example of something like "single responsibility principle"?

hadley avatar Nov 19 '18 13:11 hadley