DESCRIPTION file.object$method() for calling fields and methods.R6::R6Class() function.classname - A string used to name the class (not needed but suggested)public - A list of methods (functions) and fields (anything else)UpperCamelCase.snake_case.R6Class() into a variable with the same name as the class.self$ to access methods and fields of the current object.$new()self invisibly.$print() - Modifies the default printing method.
$print() should always return invisible(self).$initialize() - Overides the default behaviour of $new().
BankAccount <- R6Class("BankAccount", list(
owner = NULL,
type = NULL,
balance = 0,
initialize = function(owner, type) {
stopifnot(is.character(owner), length(owner) == 1)
stopifnot(is.character(type), length(type) == 1)
},
deposit = function(amount) {
self$balance <- self$balance + amount
invisible(self)
},
withdraw = function(amount) {
self$balance <- self$balance - amount
invisible(self)
}
))#> <BankAccount>
#> Public:
#> balance: 10
#> clone: function (deep = FALSE)
#> deposit: function (amount)
#> initialize: function (owner, type)
#> owner: NULL
#> type: NULL
#> withdraw: function (amount)
$print() methodBankAccount <- R6Class("BankAccount", list(
owner = NULL,
type = NULL,
balance = 0,
initialize = function(owner, type) {
stopifnot(is.character(owner), length(owner) == 1)
stopifnot(is.character(type), length(type) == 1)
self$owner <- owner
self$type <- type
},
deposit = function(amount) {
self$balance <- self$balance + amount
invisible(self)
},
withdraw = function(amount) {
self$balance <- self$balance - amount
invisible(self)
},
print = function(...) {
cat("Account owner: ", self$owner, "\n", sep = "")
cat("Account type: ", self$type, "\n", sep = "")
cat(" Balance: ", self$balance, "\n", sep = "")
invisible(self)
}
))$set() to add methods after creation.$set() are only available with new objects.inherit argument.debug() function.class() function to determine class (and all classes it inherits from).names().private - create fields and methods only available from within the class.active - allows you to use accessor functions to define dynamic or active fields.private’s interface is just like public’s interface.
private$ instead of self$
value.BankAccount <- R6Class("BankAccount", public = list(
owner = NULL,
type = NULL,
balance = 0,
initialize = function(owner, type, acct_num = NULL) {
private$acct_num <- acct_num
self$owner <- owner
self$type <- type
},
deposit = function(amount) {
self$balance <- self$balance + amount
invisible(self)
},
withdraw = function(amount) {
self$balance <- self$balance - amount
invisible(self)
},
print = function(...) {
cat("Account owner: ", self$owner, "\n", sep = "")
cat("Account type: ", self$type, "\n", sep = "")
cat("Account #: ", private$acct_num, "\n", sep = "")
cat(" Balance: ", self$balance, "\n", sep = "")
invisible(self)
}
),
private = list(
acct_num = NULL
),
active = list(
create_acct_num = function(value) {
if (is.null(private$acct_num)) {
private$acct_num <- ids::uuid()
} else {
stop("`$acct_num` already assigned")
}
}
)
)active gets its own environment.
$clone.$finalize() to clean up after yourself.$initialize(), not R6Class()$initialize() with a $finalize() method.
TemporaryDatabase <- R6Class("TemporaryDatabase", list(
con = NULL,
file = TemporaryFile$new(),
initialize = function() {
self$con <- DBI::dbConnect(RSQLite::SQLite(), path = file$path)
},
finalize = function() {
DBI::dbDisconnect(self$con)
}
))
db_a <- TemporaryDatabase$new()
db_b <- TemporaryDatabase$new()
db_a$file$path == db_b$file$path
#> [1] TRUE$intialize()TemporaryDatabase <- R6Class("TemporaryDatabase", list(
con = NULL,
file = NULL,
initialize = function() {
self$file <- TemporaryFile$new()
self$con <- DBI::dbConnect(RSQLite::SQLite(), path = file$path)
},
finalize = function() {
DBI::dbDisconnect(self$con)
}
))
db_a <- TemporaryDatabase$new()
db_b <- TemporaryDatabase$new()
db_a$file$path == db_b$file$path
#> [1] FALSE