R 中的可变默认包值

发布于 2024-12-03 11:39:51 字数 600 浏览 1 评论 0原文

我正在为 R 开发一个包,我想设置一些包范围的默认值,并能够稍后修改它们。我知道这听起来像全局变量,因此很邪恶,但我需要它来控制分析和调试并设置后端(该包可以使用各种外部程序来完成其任务,我称它们为后端)。

对于调用堆栈中的所有函数,所有这三个设置应该同时更改。例如,如果我调用 mypackage::function1(profiling = T)function1 调用 mypackage::function2mypackage:: function3 我希望就该调用而言也能对这些进行分析。一种解决方案可能是做 mypackage::turn.on.profiling() 并让所有函数引用某个包变量,但它需要锁定环境和类似的东西。

另一个可能是动态作用域,通过 sys.frame 系列函数进行模拟(也就是说,一旦分析打开,它就会针对堆栈上该点以下的任何内容打开)。不要告诉我 R 中的分析不是这样工作的,因为这是一种不同类型的分析,构建在现有分析之上,但有所不同。

我毫不怀疑我可以以某种方式破解它,但我想知道 CRAN 中是否有一个规范的解决方案,或者至少有一些针对此类问题的先例,这样我就不会重新发明轮子。

I am developing a package for R and I would like to set some package-wide defaults with the ability to modify them later. I know this sounds like global variables and thus evil, but I need this to control profiling and debugging and to set the backend (the package can use a variety of external program to do its thing and I call them backends).

All these three settings should change at the same time for all the functions in a call stack. For example, if I call mypackage::function1(profiling = T) and function1 calls mypackage::function2 and mypackage::function3 I would like profiling to be on for those too as far as that call is concerned. One solution could be to do
mypackage::turn.on.profiling() and have all the function refer to some package variable, but it requires trickery with locked environments and stuff like that.

Another could be dynamic scoping, simulated though the sys.frame family of functions (that is, once profiling is on, it's on for anything below that point on the stack). Don't tell me that profiling in R doesn't work like that because this is a different type of profiling, built on top of the existing one but different.

I have no doubt that I can hack it one way or another, but I was wondering if there is a canonical solution or at least some precedent in CRAN for something of this sort so that I won't reinvent the wheel.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

颜漓半夏 2024-12-10 11:39:51

您可以在 function1 的开头设置一个选项,并在末尾或通过 on.exit 取消设置。类似于:

function1 <- function() {
  op <- options()       # current state of options
  on.exit(options(op))  # restore when function exits
  print(getOption("mypackage.profiling"))
  options(mypackage.profiling=TRUE)  # turn on profiling
  print(getOption("mypackage.profiling"))
}
options(mypackage.profiling=FALSE)
function1()
# [1] FALSE
# [1] TRUE
getOption("mypackage.profiling")
# [1] FALSE

您还可以在包启动期间通过 .onLoad 设置选项

You could set an option at the beginning of function1 and unset it at the end or via on.exit. Something like:

function1 <- function() {
  op <- options()       # current state of options
  on.exit(options(op))  # restore when function exits
  print(getOption("mypackage.profiling"))
  options(mypackage.profiling=TRUE)  # turn on profiling
  print(getOption("mypackage.profiling"))
}
options(mypackage.profiling=FALSE)
function1()
# [1] FALSE
# [1] TRUE
getOption("mypackage.profiling")
# [1] FALSE

You could also set options during package startup via .onLoad

白芷 2024-12-10 11:39:51

另一种简单的方法是将参数放入包中的环境对象中,并让类似 turn.on.profiling 的函数对其进行修改。

# Don't export this 
.profileOptions <- new.env(parent=emptyenv())
.profileOptions$enabled <- FALSE

# export this one
profilingEnabled <- function(flag = NA) {
    oldFlag <- .profileOptions$enabled
    if (!is.na(flag)) {
       .profileOptions$enabled = flag
    }
    oldFlag
}

# then use it
profilingEnabled() # returns TRUE or FALSE
profilingEnabled(TRUE) # enables profiling, returns previous state

Another simple way is to put the parameters in an environment object in your package and have your turn.on.profiling-like function modify it.

# Don't export this 
.profileOptions <- new.env(parent=emptyenv())
.profileOptions$enabled <- FALSE

# export this one
profilingEnabled <- function(flag = NA) {
    oldFlag <- .profileOptions$enabled
    if (!is.na(flag)) {
       .profileOptions$enabled = flag
    }
    oldFlag
}

# then use it
profilingEnabled() # returns TRUE or FALSE
profilingEnabled(TRUE) # enables profiling, returns previous state
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文