Skip to content

Commit

Permalink
feat: allow prototype arguments
Browse files Browse the repository at this point in the history
Some objects have required construction arguments.
When converting a dictionary to a data.table, these prototype
arguments can be used for construction
  • Loading branch information
sebffischer committed Oct 20, 2023
1 parent 344f837 commit 8a44332
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 10 deletions.
35 changes: 31 additions & 4 deletions R/Dictionary.R
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,19 @@ Dictionary = R6::R6Class("Dictionary",
#' @param ... (`any`)\cr
#' Passed down to constructor.
#'
#' @param .prototype (`logical(1)`)\cr
#' Whether to construct a protoype object.
#'
#' @return Object with corresponding key.
get = function(key, ...) {
get = function(key, ..., .prototype = FALSE) {
assert_string(key, min.chars = 1L)
dictionary_get(self, key, ...)
assert_flag(.prototype)
args = list(...)
if (.prototype) {
args = c(args, self$prototype_args(key))
}

invoke(dictionary_get, self = self, key = key, .args = args)
},

#' @description
Expand Down Expand Up @@ -125,15 +134,21 @@ Dictionary = R6::R6Class("Dictionary",
#' Passed down to constructor.
#'
#' @param required_args (`character()`).
#' Names of arguments required for construction.
#'
#' @param .prototype_args (`list()`)\cr
#' List of arguments to construct a prototype object.
#' Can be used when objects have construction arguments without defaults.
#'
#' @return `Dictionary`.
add = function(key, value, ..., required_args = character()) {
add = function(key, value, ..., required_args = character(), .prototype_args = list()) {
assert_string(key, min.chars = 1L)
assert(check_class(value, "R6ClassGenerator"), check_r6(value), check_function(value))
assert_character(required_args, any.missing = FALSE)

dots = assert_list(list(...), names = "unique", .var.name = "additional arguments passed to Dictionary")
assign(x = key, value = list(value = value, pars = dots, required_args = required_args), envir = self$items)
assert_list(.prototype_args, names = "unique", .var.name = "prototype args")
assign(x = key, value = list(value = value, pars = dots, required_args = required_args, prototype_args = .prototype_args), envir = self$items) # nolint
invisible(self)
},

Expand Down Expand Up @@ -163,6 +178,18 @@ Dictionary = R6::R6Class("Dictionary",
required_args = function(key) {
assert_string(key, min.chars = 1L)
self$items[[key]][["required_args"]]
},

#' @description
#' Returns the arguments required to construct a simple prototype of the object.
#'
#' @param key (`character(1)`)\cr
#' Key of object to query for required arguments.
#'
#' @return `list()` of prototype arguments
prototype_args = function(key) {
assert_string(key, min.chars = 1L)
self$items[[key]][["prototype_args"]]
}
)
)
Expand Down
42 changes: 39 additions & 3 deletions man/Dictionary.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/crate.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/mlr_callbacks.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions tests/testthat/test_Dictionary.R
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,13 @@ test_that("avoid unintended partial argument matching", {
expect_r6(a, "A")
expect_equal(a$d, 1)
})


test_that("prototype_args works", {
A = R6Class("A", public = list(x = NULL, initialize = function(x) self$x = x))
d = Dictionary$new()
d$add("a", A, .prototype_args = list(x = 1))
expect_identical(d$prototype_args("a"), list(x = 1))
a = d$get("a", .prototype = TRUE)
expect_identical(a$x, 1)
})

0 comments on commit 8a44332

Please sign in to comment.