Skip to content

Commit 123d214

Browse files
authored
id as names (#232)
closes #230 alternative to #231 instead of `id` being an attribute of the `@code` elements it is now a name of the `@code` elements. Why it fits to the `names(@code)`? - id is a single value for each code element - id must be unique across all elements
1 parent 0c2455b commit 123d214

File tree

9 files changed

+50
-65
lines changed

9 files changed

+50
-65
lines changed

DESCRIPTION

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ Imports:
3030
checkmate (>= 2.1.0),
3131
grDevices,
3232
lifecycle (>= 0.2.0),
33-
rlang (>= 1.1.0)
33+
rlang (>= 1.1.0),
34+
stats,
35+
utils
3436
Suggests:
3537
cli (>= 3.4.0),
3638
knitr (>= 1.42),

R/qenv-c.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
)
2525
}
2626

27-
x_id <- get_code_attr(x, "id")
28-
y_id <- get_code_attr(y, "id")
27+
x_id <- names(x@code)
28+
y_id <- names(y@code)
2929

3030
shared_ids <- intersect(x_id, y_id)
3131
if (length(shared_ids) == 0) {
@@ -89,7 +89,7 @@ c.qenv <- function(...) {
8989
stop(join_validation)
9090
}
9191

92-
x@code <- union(x@code, y@code)
92+
x@code <- utils::modifyList(x@code, y@code)
9393

9494
# insert (and overwrite) objects from y to x
9595
x@.xData <- rlang::env_clone(x@.xData, parent = parent.env(.GlobalEnv))

R/qenv-class.R

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@
44
#' @name qenv-class
55
#' @rdname qenv-class
66
#' @slot .xData (`environment`) environment with content was generated by the evaluation
7-
#' @slot code (`list` of `character`) representing code necessary to reproduce the environment.
7+
#' @slot code (`named list` of `character`) representing code necessary to reproduce the environment.
88
#' Read more in Code section.
99
#' of the `code` slot.
1010
#'
1111
#' @section Code:
1212
#'
13-
#' Each code element is a character representing one call. Each element has possible attributes:
14-
#' - `warnings` (`character`) the warnings output when evaluating the code element
15-
#' - `messages` (`character`) the messages output when evaluating the code element
16-
#' - `id (`integer`) random identifier of the code element to make sure uniqueness when joining
13+
#' Each code element is a character representing one call. Each element is named with the random
14+
#' identifier to make sure uniqueness when joining. Each element has possible attributes:
15+
#' - `warnings` (`character`) the warnings output when evaluating the code element.
16+
#' - `messages` (`character`) the messages output when evaluating the code element.
1717
#' - `dependency` (`character`) names of objects that appear in this call and gets affected by this call,
18-
#' separated by `<-` (objects on LHS of `<-` are affected by this line, and objects on RHS are affecting this line)
18+
#' separated by `<-` (objects on LHS of `<-` are affected by this line, and objects on RHS are affecting this line).
1919
#'
2020
#' @keywords internal
2121
#' @exportClass qenv
@@ -54,11 +54,8 @@ setMethod(
5454
#' @name qenv-class
5555
#' @keywords internal
5656
setValidity("qenv", function(object) {
57-
ids <- lapply(object@code, "attr", "id")
58-
if (any(sapply(ids, is.null))) {
59-
"All @code slots must have an 'id' attribute"
60-
} else if (any(duplicated(unlist(ids)))) {
61-
"@code contains duplicated 'id' attributes."
57+
if (any(duplicated(names(object@code)))) {
58+
"@code must have unique names."
6259
} else if (!environmentIsLocked(object@.xData)) {
6360
"@.xData must be locked."
6461
} else {

R/qenv-eval_code.R

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,8 @@ setMethod("eval_code", signature = c("qenv", "character"), function(object, code
3535
object@.xData <- rlang::env_clone(object@.xData, parent = parent.env(.GlobalEnv))
3636
if (length(parsed_code) == 0) {
3737
# empty code, or just comments
38-
attr(code, "id") <- sample.int(.Machine$integer.max, size = 1)
3938
attr(code, "dependency") <- extract_dependency(parsed_code) # in case comment contains @linksto tag
40-
object@code <- c(object@code, list(code))
39+
object@code <- c(object@code, stats::setNames(list(code), sample.int(.Machine$integer.max, size = 1)))
4140
return(object)
4241
}
4342
code_split <- split_code(paste(code, collapse = "\n"))
@@ -84,10 +83,8 @@ setMethod("eval_code", signature = c("qenv", "character"), function(object, code
8483
if (!is.null(x)) {
8584
return(x)
8685
}
87-
88-
attr(current_code, "id") <- sample.int(.Machine$integer.max, size = 1)
8986
attr(current_code, "dependency") <- extract_dependency(current_call)
90-
object@code <- c(object@code, list(current_code))
87+
object@code <- c(object@code, stats::setNames(list(current_code), sample.int(.Machine$integer.max, size = 1)))
9188
}
9289

9390
lockEnvironment(object@.xData, bindings = TRUE)

man/qenv-class.Rd

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-qenv_concat.R

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ testthat::test_that("Concatenate two identical qenvs outputs", {
66
q12 <- concat(q1, q2)
77

88
testthat::expect_equal(q12@.xData, q1@.xData)
9-
testthat::expect_identical(
10-
unlist(q12@code),
11-
c("iris1 <- iris", "iris1 <- iris")
12-
)
9+
testthat::expect_identical(get_code(q12), "iris1 <- iris\niris1 <- iris")
1310
})
1411

1512
testthat::test_that("Concatenate two independent qenvs results in object having combined code and environments", {
@@ -22,13 +19,8 @@ testthat::test_that("Concatenate two independent qenvs results in object having
2219
q12 <- concat(q1, q2)
2320

2421
testthat::expect_equal(q12@.xData, list2env(list(iris1 = iris, mtcars1 = mtcars)))
25-
testthat::expect_identical(
26-
unlist(q12@code),
27-
c("iris1 <- iris", "mtcars1 <- mtcars")
28-
)
29-
q12_ids <- unlist(lapply(q12@code, "attr", "id"))
30-
q1_q2_ids <- c(attr(q1@code[[1]], "id"), attr(q2@code[[1]], "id"))
31-
testthat::expect_identical(q12_ids, q1_q2_ids)
22+
testthat::expect_identical(get_code(q12), "iris1 <- iris\nmtcars1 <- mtcars")
23+
testthat::expect_identical(names(q12@code), c(names(q1@code), names(q2@code)))
3224
})
3325

3426
testthat::test_that("Concatenate qenvs results with the same variable, the RHS has priority", {
@@ -59,7 +51,7 @@ testthat::test_that("Concatenate two independent qenvs with warnings results in
5951
q12 <- concat(q1, q2)
6052

6153
testthat::expect_equal(
62-
unlist(lapply(q12@code, attr, "warning")),
54+
unlist(lapply(q12@code, attr, "warning"), use.names = FALSE),
6355
c(
6456
"> This is warning 1\n",
6557
"> This is warning 2\n"
@@ -74,7 +66,7 @@ testthat::test_that("Concatenate two independent qenvs with messages results in
7466
q12 <- concat(q1, q2)
7567

7668
testthat::expect_equal(
77-
unlist(lapply(q12@code, attr, "message")),
69+
unlist(lapply(q12@code, attr, "message"), use.names = FALSE),
7870
c(
7971
"> This is message 1\n",
8072
"> This is message 2\n"

tests/testthat/test-qenv_eval_code.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ testthat::test_that("comments alone are pasted to the next/following call elemen
127127
code <- c("x <- 5", "# comment", "y <- 6")
128128
q <- eval_code(qenv(), code)
129129
testthat::expect_identical(
130-
unlist(q@code)[2],
130+
as.character(q@code)[2],
131131
paste(code[2:3], collapse = "\n")
132132
)
133133
testthat::expect_identical(
@@ -140,7 +140,7 @@ testthat::test_that("comments at the end of src are added to the previous call e
140140
code <- c("x <- 5", "# comment")
141141
q <- eval_code(qenv(), code)
142142
testthat::expect_identical(
143-
unlist(q@code),
143+
as.character(q@code),
144144
paste(code[1:2], collapse = "\n")
145145
)
146146
testthat::expect_identical(
@@ -153,7 +153,7 @@ testthat::test_that("comments from the same line are associated with it's call",
153153
code <- c("x <- 5", " y <- 4 # comment", "z <- 5")
154154
q <- eval_code(qenv(), code)
155155
testthat::expect_identical(
156-
unlist(q@code)[2],
156+
as.character(q@code)[2],
157157
paste0(code[2], "\n")
158158
)
159159
})
@@ -163,7 +163,7 @@ testthat::test_that("alone comments at the end of the source are considered as c
163163
code <- c("x <- 5\ny <- 10\n# comment")
164164
q <- eval_code(eval_code(qenv(), code[1]), code[2])
165165
testthat::expect_identical(
166-
unlist(q@code)[2],
166+
as.character(q@code)[2],
167167
"y <- 10\n# comment"
168168
)
169169
})

tests/testthat/test-qenv_extract.R

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,27 +41,30 @@ testthat::test_that("`[.` warns and subsets to existing if some names not presen
4141
)
4242
})
4343

44-
testthat::test_that("`[.` warns if name is in code but not in env", {
44+
testthat::test_that("`[.` warns if name is not in code but is present in env", {
4545
data <- within(qenv(), {
4646
a <- 1
4747
b <- 2
4848
c <- 3
4949
d <- 4
5050
})
5151
data@code <- data@code[1]
52-
testthat::expect_warning(data[c("a", "b", "c")])
52+
testthat::expect_warning(data[c("a", "b", "c")], "Object\\(s\\) not found in code: b, c.")
5353
})
5454

55-
testthat::test_that("`[.` doesn't warn if name is in code but not in env (secret feature for unverified teal_data)", {
56-
data <- within(qenv(), {
57-
a <- 1
58-
b <- 2
59-
c <- 3
60-
d <- 4
61-
})
62-
data@code <- data@code[1]
63-
testthat::expect_silent(data[c("a", "b", "c"), check_code_names = FALSE])
64-
})
55+
testthat::test_that(
56+
"`[.` doesn't warn if name is not in code but is present in env (secret feature for unverified teal_data)",
57+
{
58+
data <- within(qenv(), {
59+
a <- 1
60+
b <- 2
61+
c <- 3
62+
d <- 4
63+
})
64+
data@code <- data@code[1]
65+
testthat::expect_silent(data[c("a", "b", "c"), check_code_names = FALSE])
66+
}
67+
)
6568

6669
testthat::test_that("`[.` subsets environment and code to specified object names", {
6770
q <- qenv()
@@ -78,19 +81,13 @@ testthat::test_that("`[.` extracts the code only needed to recreate objects pass
7881
q <- eval_code(q, code)
7982
object_names <- c("x", "a")
8083
qs <- q[object_names]
81-
testthat::expect_identical(
82-
unlist(qs@code),
83-
c("x<-1\n", "a<-1;")
84-
)
84+
testthat::expect_identical(get_code(qs), c("x<-1\na<-1;"))
8585
})
8686

8787
testthat::test_that("`[.` comments are preserved in the code and associated with the following call", {
8888
q <- qenv()
8989
code <- c("x<-1 #comment", "a<-1;b<-2")
9090
q <- eval_code(q, code)
9191
qs <- q[c("x", "a")]
92-
testthat::expect_identical(
93-
unlist(qs@code),
94-
c("x<-1 #comment\n", "a<-1;")
95-
)
92+
testthat::expect_identical(get_code(qs), c("x<-1 #comment\na<-1;"))
9693
})

tests/testthat/test-qenv_join.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ testthat::test_that("Joining two independent qenvs with warnings results in obje
131131
q <- c(q1, q2)
132132

133133
testthat::expect_equal(
134-
get_code_attr(q, "warning"),
134+
unname(get_code_attr(q, "warning")),
135135
c(
136136
"> This is warning 1\n",
137137
"> This is warning 2\n"
@@ -146,7 +146,7 @@ testthat::test_that("Joining two independent qenvs with messages results in obje
146146
q <- c(q1, q2)
147147

148148
testthat::expect_equal(
149-
get_code_attr(q, "message"),
149+
unname(get_code_attr(q, "message")),
150150
c(
151151
"> This is message 1\n",
152152
"> This is message 2\n"

0 commit comments

Comments
 (0)