使用 R,如何基于 library::method 跟踪函数? 更新

问题描述

我正在查看函数 install_github,我认为它属于库 devtools

确实如此。它属于图书馆 remotes

当 RStudio 中触发错误时,您可以通过跟踪堆栈进行故障排除。我可以主动应用该逻辑吗?

是否有函数 traceFunction() 或可以看到返回连续 library::method 调用列表的东西?

如果该函数不存在,可以吗?

traceFunction("install_github");

更新

为了澄清,我对引用的包做了 git clonedevtools 具有以下内容

#' @importFrom remotes install_github
#' @rdname remote-reexports
#' @export
install_github <- with_pkgbuild_build_tools(with_ellipsis(remotes::install_github))

其中 remotes 具有以下内容

#' # To install from a private repo,use auth_token with a token
#' # from https://github.com/settings/tokens. You only need the
#' # repo scope. Best practice is to save your PAT in env var called
#' # GITHUB_PAT.
#' install_github("hadley/private",auth_token = "abc")
#'
#' # To pass option arguments to `R CDM INSTALL` use `INSTALL_opts`. e.g. to
#' install a package with source references and tests
#' install_github("rstudio/shiny",INSTALL_opts = c("--with-keep.source","--install-tests"))
#' }
install_github <- function(repo,ref = "HEAD",subdir = NULL,auth_token = github_pat(quiet),host = "api.github.com",dependencies = NA,upgrade = c("default","ask","always","never"),force = FALSE,quiet = FALSE,build = TRUE,build_opts = c("--no-resave-data","--no-manual","--no-build-vignettes"),build_manual = FALSE,build_vignettes = FALSE,repos = getoption("repos"),type = getoption("pkgType"),...) {

  remotes <- lapply(repo,github_remote,ref = ref,subdir = subdir,auth_token = auth_token,host = host)

  install_remotes(remotes,host = host,dependencies = dependencies,upgrade = upgrade,force = force,quiet = quiet,build = build,build_opts = build_opts,build_manual = build_manual,build_vignettes = build_vignettes,repos = repos,type = type,...)
}

调用install_remotes,我无法通过搜索存储库 remotes 中的所有“.R”文件轻松找到它。

解决方法

简短的回答,不。 R 是动态类型的并且有许多不同的类型系统(S3、S4、R6 等)。简而言之,我们看到了动态类型在调用中的效果,例如printplot。您可能已经注意到 print 对矩阵、简单向量、列表、data.frames 等的行为有所不同。plot 甚至更加多样化,可以处理前面提到的类型,以及几乎所有抛出的自定义对象从其他包(相关矩阵、热图等)到它 - 并产生截然不同的结果。

这是由于 R 的方法调度(以及针对不同类型系统的类似想法),它基本上查看作为第一个参数传递给函数的对象的类。然后它尝试为对象的类属性中的每个类调用 plot.<class>,直到某些东西起作用为止。如果没有任何效果,它会回退到 plot.default

这就是许多包可以使用 plot 函数的原因。他们实现了一个绘图函数,比如 plot.foobaz,适用于他们的 foobaz 类对象。

然后有一些方法根据输入连接函数名然后尝试调用它们

最重要的是,当一个包的方法屏蔽之前加载的包时,我们可以将不同的包扔到环境中(例如library),这可能会改变执行路径。

所以要主动找出方法的调用树,它会被限制为基于传递的实际对象。有一个包可以做到这一点,https://rdrr.io/cran/lobstr/man/cst.html