如何获取已加载包及工作区对象的srcref信息并生成列表
获取带源代码引用信息的包与工作区对象列表
嘿,我来帮你解决这个问题!先把你关心的几个关键点讲清楚,再给你能直接用的代码方案。
源代码引用在包中的工作原理
首先要明确:*源代码引用(srcref)*并不是包本身的属性,而是包内每个导出/内部对象的附加属性。只有当包在构建时保留了调试信息(比如用devtools::build(binary = FALSE, args = "--with-keep.source")构建,或者在包的DESCRIPTION文件中设置KeepSource: yes),包里的函数、对象才会带有srcref属性。
所以你的疑问是对的:要判断一个包是否有可用的源代码引用,必须扫描包内的每个对象,检查它们是否带有这个属性。你可以通过?srcfile查看更多关于源代码引用的底层细节。
解决代码:生成目标data.frame
下面是能正确获取所有已加载包、全局工作区对象及其srcref状态的代码,完全符合你的预期输出要求:
get_objects_with_srcref <- function() { # 获取所有已加载的包命名空间 loaded_pkgs <- loadedNamespaces() # 初始化结果存储列表 result_list <- list() # 遍历每个已加载的包 for (pkg in loaded_pkgs) { # 获取包内所有对象(包括隐藏对象) pkg_objects <- ls(pos = asNamespace(pkg), all.names = TRUE) for (obj_name in pkg_objects) { # 安全获取对象,避免因权限或无效对象报错 obj <- tryCatch( get(obj_name, pos = asNamespace(pkg), inherits = FALSE), error = function(e) NULL ) # 精确检查是否存在srcref属性 has_srcref <- !is.null(obj) && !is.null(attr(obj, "srcref", exact = TRUE)) # 追加到结果列表 result_list[[length(result_list) + 1]] <- data.frame( Package = pkg, Object = obj_name, Has_source_references = has_srcref, stringsAsFactors = FALSE ) } } # 处理全局工作区的对象 global_objects <- ls(pos = .GlobalEnv, all.names = TRUE) for (obj_name in global_objects) { obj <- tryCatch( get(obj_name, pos = .GlobalEnv, inherits = FALSE), error = function(e) NULL ) has_srcref <- !is.null(obj) && !is.null(attr(obj, "srcref", exact = TRUE)) result_list[[length(result_list) + 1]] <- data.frame( Package = "global", Object = obj_name, Has_source_references = has_srcref, stringsAsFactors = FALSE ) } # 合并所有结果为一个统一的data.frame do.call(rbind, result_list) } # 运行函数得到目标数据框 srcref_summary <- get_objects_with_srcref()
代码细节说明
- 用
loadedNamespaces()获取所有已加载的包,比search()更准确,因为它直接指向包的命名空间 ls(..., all.names = TRUE)确保捕获包内的隐藏对象(以.开头的对象)tryCatch用于避免获取对象时出现报错(比如某些包的内部对象无法直接访问)attr(..., exact = TRUE)精确检查srcref属性,避免误判其他类似名称的属性- 全局工作区的对象统一标记为
Package = "global",符合你的要求
额外优化提示
如果你只关心包的导出对象(而非内部未导出的对象),可以把ls(pos = asNamespace(pkg), all.names = TRUE)替换为getNamespaceExports(pkg),这样能大幅减少扫描的对象数量,提升运行效率。
另外,针对你提到的报错提示场景:当Has_source_references为FALSE时,你可以给出这样的提示:
该对象缺少源代码引用信息,报错时将无法显示对应的文件名和行号,会增加问题诊断的难度。建议重新安装保留源代码的包版本,或在编写自定义函数时避免使用会移除srcref的操作(比如
compiler::cmpfun编译函数)。
内容的提问来源于stack exchange,提问作者R Yoda
相关产品推荐
相关产品推荐

