-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
globals: Enhanced heuristic for package identification, e.g. data.table #47
Comments
#' @importFrom utils .S3methods
methods_s3 <- function(generic, base = FALSE) {
envir <- parent.frame()
s3 <- .S3methods(generic, envir = envir)
info <- attr(s3, "info")
unknown <- which(!info$visible)
## Nothing todo?
if (length(unknown) == 0) return(info)
mthds <- rownames(info)[unknown]
start <- nchar(generic) + 2L
classes <- substr(mthds, start = start, stop = nchar(mthds))
ns <- vapply(classes, FUN = function(class) {
ns <- environment(getS3method(generic, class = class, envir = envir))
if (isBaseNamespace(ns)) return("base")
.getNamespaceInfo(ns, "spec")["name"]
}, FUN.VALUE = NA_character_, USE.NAMES = FALSE)
namespace <- as.character(info$from)
namespace[unknown] <- ns
info$namespace <- namespace
if (!base) {
unamespace <- unique(namespace)
is_base <- vapply(unamespace, FUN = is_base_pkg, FUN.VALUE = FALSE, USE.NAMES = FALSE)
unamespace <- unamespace[!is_base]
if (length(unamespace) == 0) {
info <- info[integer(0), ]
} else {
info <- info[namespace %in% unamespace, ]
}
}
info
} > library(data.table)
> methods_s3("[")
visible from generic isS4 namespace
[.data.table FALSE registered S3method for [ [ FALSE data.table
[.Globals FALSE registered S3method for [ [ FALSE globals
[.ITime FALSE registered S3method for [ [ FALSE data.table |
#' @importFrom utils .S3methods
packagesOfS3Methods <- function(generic, base = FALSE) {
envir <- parent.frame()
s3 <- .S3methods(generic, envir = envir)
info <- attr(s3, "info")
namespace <- as.character(info$from)
unknown <- which(!info$visible)
if (length(unknown) > 0) {
mthds <- rownames(info)[unknown]
start <- nchar(generic) + 2L
classes <- substr(mthds, start = start, stop = nchar(mthds))
ns <- vapply(classes, FUN = function(class) {
ns <- environment(getS3method(generic, class = class, envir = envir))
if (isBaseNamespace(ns)) return("base")
.getNamespaceInfo(ns, "spec")["name"]
}, FUN.VALUE = NA_character_, USE.NAMES = FALSE)
namespace[unknown] <- ns
}
unamespace <- unique(namespace)
if (!base) {
is_base <- vapply(unamespace, FUN = is_base_pkg, FUN.VALUE = FALSE, USE.NAMES = FALSE)
unamespace <- unamespace[!is_base]
}
unamespace
} > library(data.table)
> packagesOfS3Methods("[")
[1] "data.table" "globals" |
This was referenced Jun 12, 2019
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
After
globalsOf()
has gathered all globals and packages it could do another round and look among the generic functions whether there are any S3 methods registered with any of the loaded namespaces not yet in the list of packages, cf.attr(methods("["), "info")
(*). That would provide an upper bound of additional packages that need to be loaded. This should for instance pick up the data.table package when[
is in the set of globals.To make this a bit more conservative, one could, in turn, scan the global variables to identify classes and match those to the table of registered (package, generic, class) methods.
(*) Unfortunately, namespace/package information is lost in
methods("[")
- we might have to roll our own version where this information is retained. See also https://twitter.com/henrikbengtsson/status/1026745698514087936The text was updated successfully, but these errors were encountered: