diff --git a/R/data.R b/R/data.R index 6243fdfa..0478ed85 100644 --- a/R/data.R +++ b/R/data.R @@ -29,7 +29,7 @@ S7_data <- function(object) { `S7_data<-` <- function(object, check = TRUE, value) { attrs <- attributes(object) object <- value - attributes(object) <- attrs + attributes(object) <- modify_list(attrs, attributes(value)) if (isTRUE(check)) { validate(object) } diff --git a/tests/testthat/test-data.R b/tests/testthat/test-data.R index d25990d6..97d89be8 100644 --- a/tests/testthat/test-data.R +++ b/tests/testthat/test-data.R @@ -20,3 +20,32 @@ describe("S7_data", { expect_equal(S7_data(x), "bar") }) }) + + +describe("S7_data<-", { + + it("uses updated 'names'", { + # local_methods(`$<-`, `[[<-`) # no support for unregistering S3 generic methods + + write_once_list <- new_class("write_once_list", class_list, + constructor = function(...) new_object(list(...)) + ) + + method(`$<-`, write_once_list) <- + method(`[[<-`, write_once_list) <- function(x, name, value) { + .x <- S7_data(x) + stopifnot(is_string(name)) + if (hasName(.x, name)) + stop("entry exists: ", name) + .x[[name]] <- value + S7_data(x) <- .x + x + } + w <- write_once_list(x = 3, y = 4) + w$bar <- 1 + expect_equal(names(w), c("x", "y", "bar")) + expect_error(w$bar <- 2, "entry exists:") + + }) + +})