Skip to content

Instantly share code, notes, and snippets.

@lionel-
Last active December 2, 2017 14:01
Show Gist options
  • Save lionel-/e0222bfe396b846a99ec2dd7a1ed1269 to your computer and use it in GitHub Desktop.
Save lionel-/e0222bfe396b846a99ec2dd7a1ed1269 to your computer and use it in GitHub Desktop.
Handle hard dependencies in library()
depend <- function(..., character.only = FALSE) {
# Mimic library()'s UI
if (character.only) {
packages <- c(...)
} else {
packages <- substitute(c(...))[-1]
if (!all(vapply(packages, is.symbol, logical(1)))) {
stop("Can't supply expressions if `character.only` is FALSE")
}
packages <- as.character(packages)
}
stopifnot(is.character(packages))
lapply(packages, library, character.only = TRUE)
packages <- paste0("package:", packages)
packages <- unique(c(globalenv()$.__deps__., packages))
assign(".__deps__.", packages, envir = globalenv())
invisible(NULL)
}
library <- function(package, help, pos = 2, lib.loc = NULL,
character.only = FALSE, logical.return = FALSE,
warn.conflicts = TRUE, quietly = FALSE,
verbose = getOption("verbose")) {
deps <- globalenv()$.__deps__.
# Some ugliness to work around the fact that library() quotes some
# of its arguments
library_call <- sys.call()
library_call[[1]] <- quote(base::library)
# No deps, forward to base::library()
if (is.null(deps)) {
return(eval(library_call, parent.frame()))
}
if (!character.only) {
package <- as.character(substitute(package))
}
stopifnot(is.character(package), length(package) == 1)
positions <- match(deps, search())
if (anyNA(positions)) {
stop("Can't find dependency on the search path!")
}
library_call$pos <- max(positions) + 1L
eval(library_call, parent.frame())
}
depend(stats, graphics)
library(dplyr)
#> Attaching package: ‘dplyr’
#>
#> The following objects are masked _by_ ‘package:stats’:
#>
#> filter, lag
#>
#> The following objects are masked from ‘package:base’:
#>
#> intersect, setdiff, setequal, union
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment