Skip to content

Commit 2810995

Browse files
BUG FIX: as.Globals(list(a = NULL)) would include the calling environment instead of an empty environment as part of the 'where' attribute (fix #79)
1 parent 7239616 commit 2810995

File tree

6 files changed

+52
-20
lines changed

6 files changed

+52
-20
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Package: globals
2-
Version: 0.14.0-9000
2+
Version: 0.14.0-9002
33
Depends:
44
R (>= 3.1.2)
55
Imports:

NEWS

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
Package: globals
22
================
33

4-
Version: 0.14.0-9000 [2020-11-22]
4+
Version: 0.14.0-9002 [2022-05-06]
55

6-
* ...
7-
6+
BUG FIXES:
7+
8+
* as.Globals(list(a = NULL)) and c(Globals(), list(a = NULL)) would
9+
include the calling environment instead of an empty environment as
10+
part of the 'where' attribute.
11+
812

913
Version: 0.14.0 [2020-11-22]
1014

R/Globals-class.R

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,7 @@ as.Globals.list <- function(x, ...) {
5858
## (with emptyenv() as the fallback)
5959
where <- attr(x, "where", exact = TRUE)
6060
if (is.null(where)) {
61-
where <- lapply(x, FUN = function(obj) {
62-
e <- environment(obj)
63-
if (is.null(e)) e <- emptyenv()
64-
e
65-
})
61+
where <- lapply(x, FUN = environment_of)
6662
names(where) <- names(x)
6763
attr(x, "where") <- where
6864
}
@@ -115,10 +111,8 @@ as.Globals.list <- function(x, ...) {
115111
x[[name]] <- value[[1]]
116112
where[[name]] <- attr(value, "where", exact = TRUE)[[1]]
117113
} else {
118-
w <- environment(value)
119-
if (is.null(w)) w <- emptyenv()
120114
x[[name]] <- value
121-
where[[name]] <- w
115+
where[[name]] <- environment_of(value)
122116
}
123117
}
124118

@@ -148,19 +142,14 @@ c.Globals <- function(x, ...) {
148142

149143
names <- names(g)
150144
stop_if_not(!is.null(names))
151-
w <- lapply(g, FUN = function(obj) {
152-
e <- environment(obj)
153-
if (is.null(e)) e <- emptyenv()
154-
e
155-
})
145+
w <- lapply(g, FUN = environment_of)
156146
names(w) <- names
157147
} else {
158148
if (is.null(name)) {
159149
stopf("Can only append named objects to Globals list: %s", sQuote(mode(g)))
160150
}
161151
g <- structure(list(g), names = name)
162-
e <- environment(g)
163-
if (is.null(e)) e <- emptyenv()
152+
e <- environment_of(g)
164153
w <- structure(list(e), names = name)
165154
}
166155
where <- c(where, w)

R/environment_of.R

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# A safe version of base::environment() that returns emptyenv()
2+
# if NULL is passed, instead of the calling environment.
3+
# Related to https://github.com/HenrikBengtsson/globals/issues/79
4+
environment_of <- function(obj) {
5+
if (is.null(obj)) return(emptyenv())
6+
e <- environment(obj)
7+
if (is.null(e)) return(emptyenv())
8+
e
9+
}

R/packagesOf.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ packagesOf.Globals <- function(globals, ...) {
1414
## Scan 'globals' for which packages needs to be loaded.
1515
## This information is in the environment name of the objects.
1616
pkgs <- vapply(globals, FUN = function(obj) {
17-
environmentName(environment(obj))
17+
environmentName(environment_of(obj))
1818
}, FUN.VALUE = "", USE.NAMES = FALSE)
1919

2020
## Drop "missing" packages, e.g. globals in globalenv().

tests/Globals.R

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,36 @@ globals <- as.Globals(list())
246246
message("*** Globals() - empty ... DONE")
247247

248248

249+
message("*** Globals() - NULL ...")
250+
## https://github.com/HenrikBengtsson/globals/issues/79
251+
252+
globals <- as.Globals(list(a = NULL))
253+
str(globals)
254+
where <- attr(globals, "where")
255+
stopifnot(
256+
length(globals) == 1L,
257+
length(where) == length(globals),
258+
all(names(where) == names(globals)),
259+
identical(names(globals), c("a")),
260+
is.null(globals[["a"]]),
261+
identical(where[["a"]], emptyenv())
262+
)
263+
264+
globals <- c(Globals(), list(a = NULL))
265+
str(globals)
266+
where <- attr(globals, "where")
267+
stopifnot(
268+
length(globals) == 1L,
269+
length(where) == length(globals),
270+
all(names(where) == names(globals)),
271+
identical(names(globals), c("a")),
272+
is.null(globals[["a"]]),
273+
identical(where[["a"]], emptyenv())
274+
)
275+
276+
message("*** Globals() - NULL ... DONE")
277+
278+
249279
message("*** Globals() - exceptions ...")
250280

251281
res <- tryCatch({ Globals(NULL) }, error = identity)

0 commit comments

Comments
 (0)