Skip to content

Commit 903a43c

Browse files
committed
feat: qenv constructor improvement
1 parent bf5ed47 commit 903a43c

File tree

4 files changed

+43
-10
lines changed

4 files changed

+43
-10
lines changed

R/qenv-class.R

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,43 @@ setClass(
2828
setMethod(
2929
"initialize",
3030
"qenv",
31-
function(.Object, .xData = new.env(parent = parent.env(.GlobalEnv)), ...) { # nolint: object_name.
32-
# .xData needs to be unnamed as the `.environment` constructure requires 1
33-
# unnamed formal argument. See methods::findMethods("initialize")$.environment
34-
.Object <- methods::callNextMethod(.Object, .xData, ...) # nolint: object_name.
31+
function(.Object, # nolint: object_name.
32+
.xData, # nolint: object_name.
33+
code = character(0L),
34+
warnings = rep("", length(code)),
35+
messages = rep("", length(code)),
36+
id = integer(0L),
37+
...) {
38+
# # Pre-process parameters to ensure they are ready to be used by parent constructors
39+
stopifnot("`code` must be a character or language object." = any(is.language(code), is.character(code)))
3540

36-
checkmate::assert_environment(.xData)
37-
lockEnvironment(.xData, bindings = TRUE)
38-
.Object@.xData <- .xData # nolint: object_name.
41+
if (is.language(code)) {
42+
code <- paste(lang2calls(code), collapse = "\n")
43+
}
44+
if (length(code)) {
45+
code <- paste(code, collapse = "\n")
46+
}
47+
48+
if (length(id) == 0L) {
49+
id <- sample.int(.Machine$integer.max, size = length(code))
50+
}
51+
52+
new_xdata <- if (rlang::is_missing(.xData)) {
53+
new.env(parent = parent.env(.GlobalEnv))
54+
} else {
55+
checkmate::assert_environment(.xData)
56+
rlang::env_clone(.xData, parent = parent.env(.GlobalEnv))
57+
}
58+
lockEnvironment(new_xdata, bindings = TRUE)
59+
60+
# .xData needs to be unnamed as the `.environment` constructor allows at
61+
# most 1 unnamed formal argument of class `environment`.
62+
# See methods::findMethods("initialize")$.environment
63+
.Object <- methods::callNextMethod( # nolint: object_name.
64+
# Mandatory use of `xData` to build a correct [email protected]
65+
.Object, new_xdata,
66+
code = code, messages = messages, warnings = warnings, id = id, ...
67+
)
3968

4069
.Object
4170
}

tests/testthat/test-qenv-class.R

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,8 @@ testthat::describe("methods::new(qenv)", {
1717
testthat::it("throws error when .xData is not an environment", {
1818
expect_error(methods::new("qenv", .xData = 2), "Must be an environment, not 'double'\\.")
1919
})
20+
21+
testthat::it("throws error when code is not language or character object", {
22+
expect_error(methods::new("qenv", code = 2), "`code` must be a character or language object\\.")
23+
})
2024
})

tests/testthat/test-qenv_eval_code.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ testthat::test_that("eval_code evaluates the code in the qenvs environment", {
22
q <- qenv()
33
q1 <- eval_code(q, quote(iris1 <- iris))
44
q2 <- eval_code(q1, quote(b <- nrow(iris1)))
5-
testthat::expect_identical(get_var(q2, "b"), 150L)
5+
testthat::expect_identical(q2$b, 150L)
66
})
77

88
testthat::test_that("eval_code doesn't have access to environment where it's called", {

tests/testthat/test-qenv_join.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,15 @@ testthat::test_that("Not possible to join qenvs which share some code when one o
8585
q1 <- eval_code(q1, quote(iris2 <- iris))
8686
q2 <- eval_code(q2, quote(mtcars1 <- head(mtcars)))
8787

88-
testthat::expect_error(join(q1, q2))
88+
testthat::expect_error(c(q1, q2))
8989
})
9090

9191
testthat::test_that("qenv objects are mergeable if they don't share any code (identified by id)", {
9292
q1 <- eval_code(qenv(), code = quote(a1 <- 1))
9393
q2 <- eval_code(qenv(), code = quote(a1 <- 1))
9494
testthat::expect_true(.check_joinable(q1, q2))
9595

96-
cq <- join(q1, q2)
96+
cq <- c(q1, q2)
9797
testthat::expect_s4_class(cq, "qenv")
9898
testthat::expect_equal(cq@.xData, list2env(list(a1 = 1)))
9999
testthat::expect_identical(cq@code, c("a1 <- 1", "a1 <- 1"))

0 commit comments

Comments
 (0)