Nothing
#' Unload a package
#'
#' @description
#'
#' `unload()` attempts to cleanly unload a package, including unloading
#' its namespace, deleting S4 class definitions and unloading any loaded
#' DLLs. Unfortunately S4 classes are not really designed to be cleanly
#' unloaded, and so we have to manually modify the class dependency graph in
#' order for it to work - this works on the cases for which we have tested
#' but there may be others. Similarly, automated DLL unloading is best tested
#' for simple scenarios (particularly with `useDynLib(pkgname)` and may
#' fail in other cases. If you do encounter a failure, please file a bug report
#' at \url{https://github.com/r-lib/pkgload/issues}.
#'
#' `unregister()` is a gentler version of `unload()` which removes the
#' package from the search path, unregisters methods, and unregisters
#' the namespace. It doesn't unload the namespace or its DLL to keep
#' it in working order in case of dangling references.
#'
#' @inheritParams ns_env
#' @param quiet if `TRUE` suppresses output from this function.
#'
#' @examples
#' \dontrun{
#' # Unload package that is in current directory
#' unload()
#'
#' # Unload package that is in ./ggplot2/
#' unload(pkg_name("ggplot2/"))
#'
#' library(ggplot2)
#' # unload the ggplot2 package directly by name
#' unload("ggplot2")
#' }
#' @export
unload <- function(package = pkg_name(), quiet = FALSE) {
if (package == "compiler") {
# Disable JIT compilation as it could interfere with the compiler
# unloading. Also, if the JIT was kept enabled, it would cause the
# compiler package to be loaded again soon, anyway. Note if we
# restored the JIT level after the unloading, the call to
# enableJIT itself would load the compiler again.
oldEnable <- compiler::enableJIT(0)
if (oldEnable != 0) {
cli::cli_warn("JIT automatically disabled when unloading the compiler.")
}
}
if (!package %in% loadedNamespaces()) {
cli::cli_abort("Package {.pkg {package}} not found in loaded packages or namespaces.")
}
unregister_methods(package)
# unloadNamespace calls onUnload hook and .onUnload, and detaches the
# package if it's attached. It will fail if a loaded package needs it.
unloaded <- tryCatch({
unloadNamespace(package)
TRUE
}, error = function(e) FALSE)
if (!unloaded) {
# unloadNamespace() failed before we get to the detach, so need to
# manually detach
unload_pkg_env(package)
# Can't use loadedNamespaces() and unloadNamespace() here because
# things can be in a weird state.
unregister_namespace(package)
}
# Clear so that loading the package again will re-read all files
clear_cache()
# Do this after detach, so that packages that have an .onUnload function
# which unloads DLLs (like MASS) won't try to unload the DLL twice.
unload_dll(package)
}
#' @rdname unload
#' @export
unregister <- function(package = pkg_name()) {
# Before unregistering anything, force all imported functions that
# might be needed during package reloading, in case they come from
# `package`
force_load_all_deps()
unload_pkg_env(package)
unregister_methods(package)
unregister_namespace(package)
}
unload_pkg_env <- function(package) {
if (is_attached(package)) {
pos <- which(pkg_env_name(package) == search())
suppressWarnings(detach(pos = pos, force = TRUE))
}
}
# This unloads dlls loaded by either library() or load_all()
unload_dll <- function(package) {
# Always run garbage collector to force any deleted external pointers to
# finalise
gc()
# Special case for devtools - don't unload DLL because we need to be able
# to access nsreg() in the DLL in order to run makeNamespace. This means
# that changes to compiled code in devtools can't be reloaded with
# load_all -- it requires a reinstallation.
if (package == "pkgload") {
return(invisible())
}
pkglibs <- loaded_dlls(package)
for (lib in pkglibs) {
dyn.unload(lib[["path"]])
}
# Remove the unloaded dlls from .dynLibs()
libs <- .dynLibs()
.dynLibs(libs[!(libs %in% pkglibs)])
invisible()
}
s3_unregister <- function(package) {
ns <- ns_env(package)
# If the package is loaded, but not installed this will fail, so we bail out in that case.
ns_defs <- suppressWarnings(try(parse_ns_file(system.file(package = package)), silent = TRUE))
if (inherits(ns_defs, "try-error")) {
return()
}
methods <- ns_defs$S3methods[, 1:2, drop = FALSE]
for (i in seq_len(nrow(methods))) {
method <- methods[i, , drop = FALSE]
generic <- env_get(ns, method[[1]], inherit = TRUE, default = NULL)
if (is_null(generic)) {
next
}
generic_ns <- topenv(fn_env(generic))
if (!is_namespace(generic_ns)) {
next
}
# Don't remove methods for generics defined in the namespace being
# unloaded. The stale namespace should still work as much as
# possible.
if (is_string(ns_env_name(generic_ns), package)) {
next
}
table <- generic_ns$.__S3MethodsTable__.
if (!is_environment(table)) {
next
}
nm <- paste0(method, collapse = ".")
env_unbind(table, nm)
}
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.