在一个包中,我有一个 main 函数,它调用许多其他未导出的函数,并且到处都有大量条件检查。
当使用 tidyverse 错误处理时,例如使用 Awesome {cli}包中,您可以附加将用于装饰函数的调用者环境。该文档可用 here .
这里是一些示例代码:
main = function() f1()
f1 = function() f2()
f2 = function() cli::cli_abort("foobar", call=rlang::caller_env())
main()
#> Error in `f1()`:
#> ! foobar
由 reprex package 于 2022 年 7 月 3 日创建(v2.0.1)
调用者不是 f2()
而是其父 f1()
,但该错误仍然不提供信息,因为最终用户不知道内部 f1()
函数之一。
要让 main()
作为最终调用者,我可以编写 call=rlang::caller_env(2)
(这不太容易维护),或者传递调用者作为每个堆栈函数中的参数,这将需要大量重构。
有没有办法拥有一个全局变量来充当对 main()
的引用,并且我可以在代码中的任何位置使用它?
最佳答案
我能想到的唯一(hacky)选项:
1:继续一次向上 1 个父环境,直到到达 R_GlobalEnv
,然后返回 1 步。
main = function() f1()
f1 = function() f2()
f2 = function() {
for(depth in 1:10) if(identical(rlang::caller_env(depth), globalenv())) break
if(depth == 10) depth = 1
cli::cli_abort("foobar", call=rlang::caller_env(depth-1))
}
main()
2:自己创建某种可以搜索的标识符
main = function() {
marker = "hello!"
f1()
}
f1 = function() f2()
f2 = function() {
for(depth in 1:10) try( if( get('marker', envir = rlang::caller_env(depth)) == "hello!" ) break, silent = T)
if(depth == 10) depth = 0
cli::cli_abort("foobar", call=rlang::caller_env(depth))
}
main()
关于r - 如何让main函数环境固定为 "anchor"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72844255/