R6
R6 copied to clipboard
Guidance on declaration and default values of a field
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 viafoo = 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 theR6Class()
call is inside a function, which is rare. This underscores the wisdom of usingNULL
in the placeholder and putting default logic in the initializer.
cc and thanks @gaborcsardi @hadley
Example of something like "single responsibility principle"?