Bug Fixes

  • globalsByName(), and therefore also globalsOf(), did not support special arguments ..1, ..2, etc.

  • cleanup(globals, drop) on a Globals object with non-existing globals and where drop did not specify "missing" would throw an Error in exists(name, envir = env) : use of NULL environment is defunct. Now the non-existing (“missing”) globals are preserved.

Documentation

Bug Fixes

  • packagesOf() for Globals failed to return the package of the globals if the global doesn’t have a closure, e.g. base::pi and data.table::.N.

New Features

  • Add [[<- and [<- for Globals, to complement $<-.

Reproducibility

  • All functions modifying a Globals object guarantee that the where and the class attributes are always the last two attributes and in that order.

Bug Fixes

  • c() for Globals would lose the where environment for any functions appended.

Bug Fixes

  • cleanup() assumed it was safe to call env$.packageName on each scanned environment, but that might not be true. A classed environment could be such that $() gives an error, rather than returning something.

New Features

  • globalsOf() gained argument locals, which controls whether globals that exist in “local” environments of a function should be considered or not, e.g. in f <- local({ a <- 1; function() a }), should a be considered a global of f() or not. For backward compatibility reasons, the default is locals = TRUE, but this might become locals = FALSE in a later release.

  • Any globals.* options specific to this packages can now be set via environment variables R_GLOBALS_* when the package is loaded. For example, R_GLOBALS_DEBUG=true sets option globals.debug = TRUE.

Bug Fixes

  • as.Globals(list(a = NULL)) and c(Globals(), list(a = NULL)) would include the calling environment instead of an empty environment as part of the where attribute.

New Features

  • Now findGlobals(function(x) x <- x) identifies x as a global variable.

  • Now findGlobals(function(x) x[1] <- 0) identifies x as a global variable. Same for other variants like x[[1]] <- 0 and x$a <- 0.

  • Now findGlobals(function(z) x <- z$x) identifies x as a global variable.

  • Now findGlobals(quote({ f <- function(x) x; x })) identifies x as a global variable. Previously, the x of the function would hide the global x.

Bug Fixes

  • globalsOf() could produce “Error in vapply(where, FUN = envname, FUN.VALUE = NA_character_, USE.NAMES = FALSE) : values must be length 1, but FUN(X[[2]]) result is length 10”. This would happen if for instance argument envir has attributes set.

  • findGlobals() works around a bug in stats:::[.formula of R (< 4.1.0) that revealed itself when scanning formulas with NULL components.

  • findGlobals() would not pass down argument dotdotdot when recursively parsing assignments.

  • findGlobals() could return ... as a global also when used in formulas. Now it respects argument dotdotdot = "ignore" and parses formulas accordingly, otherwise formulas will be parsed using dotdotdot = "return".

Significant Changes

  • findGlobals(expr) now also scans any attributes of expr for globals, e.g. purrr::partial() puts the original function in attribute body. Argument attributes controls which attributes, if any, should be scanned. Default is to scan all attributes.

  • findGlobals(), globalsOf(), and globalsByName() now recognizes and returns values for ..1, ..2, etc. like they do for ....

  • cleanup() now also drop exported and non-exported NativeSymbolInfo objects.

New Features

  • cleanup() gained support for dropping NativeSymbolInfo objects.

Bug Fixes

  • findGlobals() did not pass down argument method in recursive calls.

  • findGlobals(expr) would fail to identify globals in anonymous function calls, e.g. expr <- as.call(list(function(...) NOT_FOUND, quote(FOUND))).

  • Calls like findGlobals(~ NULL) with NULLs on the right-hand side could throw “Error in if (length(ans) == 0L || as.character(ans[[1L]])[1L] ==”~“) { : missing value where TRUE/FALSE needed”. Solved by working around what looks like a bug in the stats package causing subsetting on formulas with NULLs to fail.

  • cleanup(..., drop = c(..., "base-packages")) for Globals would drop base R objects with names not exported by the corresponding base R package. Similarly, drop = c(..., "primitive") would drop primitive R objects with names not exported by any base R package.

  • findGlobals(), globalsOf(), and globalsByName() did not handle ..1, ..2, etc.

  • findGlobals() and globalsOf() produces warnings on ‘: … may be used in an incorrect context’ when formulas had ..., ..1, ..2, etc.

  • findGlobals(function() NULL, substitute = TRUE, trace = TRUE) would throw “Error in environment(w$enterLocal) : object ‘w’ not found”.

Bug Fixes

  • findGlobals(function() { a; a <- a + 1 }) would fail to identify a as a global variable whereas it was properly identified with { a <- a + 1; a }.

Bug Fixes

  • globalsOf() could produce “Error in vapply(where, FUN = envname, FUN.VALUE = NA_character_, USE.NAMES = FALSE) : values must be length 1, but FUN(X[[…]]) result is length …”. This was because the internal envname(env) did not always handle when class(env) != "environment".

New Features

Bug Fixes

  • globals::findGlobals() would not identify a as a global in expressions of type a[1] = ... and names(a) = ... although it did for a[1] <- ... and names(a) <- ....

Performance

  • cleanup() for Globals should now be much faster. Previously, it could be very slow the first time it was called in a fresh R session, especially if the user had a large number of packages installed and/or the package libraries were on slow drives.

Documentation

Bug Fixes

  • globals::findGlobals(x), where x is a list, iterated over x incorrectly assuming no method dispatching on x would take place. For instance, if x contained an fst::fst_table object, then “Error in .subset2(x, i, exact = exact) : subscript out of bounds” would be produced.

  • globals::findGlobals() could produce a “Warning in is.na(x): is.na() applied to non-(list or vector) of type ‘NULL’” in R (< 3.5.0).

Performance

  • globals::findGlobals() is now significantly faster for elements that are long lists with many elements of basic data types. This is because elements of such basic data type cannot contain globals and can therefore be skipped early in the search for globals.

New Features

  • Now globals::findGlobals() identifies a as a global also when it is part of LHS expressions of type a[1] <- ... and names(a) <- ....

Bug Fixes

  • globals::findGlobals() incorrectly identified a as a global in expression of type a <- pkg::a.

  • If ... was passed to globalsByName(names), an error would be produced unless it was the last entry in names.

New Features

  • Now findGlobals() identifies x as a global variable in x <- x + 1 and likewise for x + 1 -> x. Note that ditto using <<- and ->> was already identifying x as a global.

Bug Fixes

  • findGlobals(..., trace = TRUE) now outputs only to standard error. Previously, some of the output went to standard output.

Bug Fixes

  • globalsOf(..., recursive = TRUE) would result in “Error in match.fun(FUN) : node stack overflow” if one of the globals identified was a function that called itself recursively (either directly or indirectly).

Bug Fixes

  • walkAST() could produce error “Cannot walk expression. Unknown object type ‘…’” for objects of type environment.

Bug Fixes

  • walkAST() could produce error “Cannot walk expression. Unknown object type ‘…’” for objects of type list, expression and S4.

New Features

  • Globals that are part of a formula are now identified.

  • findGlobals(..., trace = TRUE) will now show low-level parse information as the abstract syntax tree (AST) is walked.

SOFTWARE QUALITY:

  • Enabled more internal sanity checks.

Bug Fixes

  • walkAST() could produce error “Cannot walk expression. Unknown object type ‘nnn’” for expressions of type builtin, closure and special.

New Features

  • Added option globals.debug, which when TRUE enables debugging output.

Bug Fixes

  • globalsOf(..., recursive = TRUE) would in some cases scan an incorrect subset of already identified globals.

  • globalsOf(..., recursive = TRUE) failed to skip objects part of package namespaces that where defined via a local() statement.

New Features

  • globalsOf() identifies also globals in locally defined functions. This can be disabled with argument recursive = FALSE.

  • findGlobals() now takes both closures (functions) and expressions.

Bug Fixes

  • c(x, list()) where x is a Globals object would give an error reporting that the list does not have named elements.

New Features

Bug Fixes

  • walkAST(quote( function(x=NULL) 0 )) would give a sanity check error due to the NULL argument. Thank you GitHub user ‘billy34’ for reporting on this.

New Features

New Features

  • Now the error message of globalsOf(..., mustExist = TRUE) when it fails to locate a global also gives information on the expression that is problematic.

Bug Fixes

  • cleanup() for Globals did not cleanup functions in core package environments named package:<name>.

New Features

  • findGlobals() is updated to handle the case where a local variable is overwriting a global one with the same name, e.g. { a <- b; b <- 1 }. Now b is correctly identified as a global object. Previously it would have been missed. For backward compatibility, the previous behavior can be obtained using argument method = "conservative".

New Features

  • globalsOf() now returns attribute where specifying where each global object is located.

Bug Fixes

  • cleanup() now only drops objects that are located in one of the “base” packages; previously it would also drop copies of such objects, e.g. FUN <- base::sample.

Bug Fixes

  • globalsOf() failed to return global variables with value NULL. They were identified but silently dropped.

New Features

  • More test coverage.

New Features

New Features

  • Added [() for Globals.

  • findGlobals() and getGlobals() gained argument substitute.

  • Added cleanup(..., method = "internals").

New Features

New Features

  • getGlobals() gained argument mustExist for controlling whether to give an error when the corresponding object for an identified global cannot be found or to silently drop the missing global.

  • findGlobals() and getGlobals() gained argument method for controlling whether a "conservative" or a "liberal" algorithm for identifying true globals should be used.

  • Moved “globals” functions from an in-house package to this package.
  • Created.