我在考虑这样的事情:
> fx = function(x, y) {
+ if (exists("debugging")) {
+ print(x)
+ print(y)
+ }
+ x+y
+ }
> fx(1, 2)
[1] 3
> debugging = 1
> fx(2, 3)
[1] 2
[1] 3
[1] 5
通过这种方式,您可以根据需要编写任意数量的调试消息,当您想要将其关闭时,您只需
rm(debugging)
问题是变量调试(或任何你给它的名称)可以随时被任何其他包删除或创建,这很难控制。有什么想法吗?
答案 0 :(得分:6)
使用选项。如果xyz
是包的名称,则典型函数中的调试代码将执行此操作:
if (getOption("xyz.debug", FALSE)) { print(x); print(y) }
然后在包外面发出这个以打开调试:
options(xyz.debug = TRUE)
或将其关闭:
options(xyz.debug = FALSE) # or options(xyz.debug = NULL)
另一个软件包不太可能有一个以软件包名称为前缀的选项名称。
这种方法的主要优点是它不需要除if (...) ...
语句之外的任何基础结构,使其非常轻量级,并且在调试关闭的情况下使用它的开销只是{{1} }并致电if
。
答案 1 :(得分:4)
另一种选择是在您的包中定义debugging
函数:
debugging <- local({
stored.value <- FALSE
function(bool = NULL)
if (is.null(bool)) {
stored.value
} else {
stopifnot(is.logical(bool), length(bool) == 1L)
stored.value <<- bool
}
})
# default value:
debugging()
# [1] FALSE
# set value
debugging(TRUE)
# check value
debugging()
# [1] TRUE
这可以解决您对“如果我决定稍后更改包名怎么办?”的担忧。我想。
答案 2 :(得分:-1)
仅仅是为了记录,这是我在阅读@ G.Grothendieck的回答后想出的:
dbgexec = function(cmd) {
command = substitute(cmd)
if(getOption("mypack.debug", FALSE)) eval(cmd, parent.frame())
invisible(NULL)
}
示例:
> x = 1.1111
> dbgexec({message("value of x: "); print(x)})
value of x:
[1] 1.1111
> options(mypack.debug = FALSE)
> dbgexec({message("value of x: "); print(x)})
# nothing done here
和@ flodel的回答实验:
> debugging <- local({
+ stored.value <- FALSE
+ function(bool = NULL)
+ if (is.null(bool)) {
+ stored.value
+ } else {
+ stopifnot(is.logical(bool), length(bool) == 1L)
+ stored.value <<- bool
+ }
+ })
>
>
> dbgexec = function(cmd) {
+ command = substitute(cmd)
+ if(debugging()) eval(cmd, parent.frame())
+ invisible(NULL)
+ }
>
> x = 1; y = 2
> dbgexec({x <- 2; y <- 3; print(x + y)})
> x
[1] 1
> y
[1] 2
> debugging()
[1] FALSE
> debugging(TRUE)
> dbgexec({x <- 2; y <- 3; print(x + y)})
[1] 5
> x
[1] 2
> y
[1] 3