Reputation: 23114
I am thinking of something like this:
> 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
This way you can write as many debugging messages as you want, and when you want to turn them off, you just
rm(debugging)
The problem is the variable debugging (or any name that you give it) can be removed or created by any other package anytime, which is hard to control. Any ideas?
Upvotes: 2
Views: 122
Reputation: 269714
Use an option. If xyz
is the name of your package the debugging code in a typical function would do this:
if (getOption("xyz.debug", FALSE)) { print(x); print(y) }
Then outside the package issue this to turn on debugging:
options(xyz.debug = TRUE)
or this to turn it off:
options(xyz.debug = FALSE) # or options(xyz.debug = NULL)
Its not likely that another package will have an option name prefixed with the name of your package.
The main advantages of this approach are that it does not require any infrastructure other than the if (...) ...
statements making it quite lightweight and the overhead for using it in the case that debugging is off is just an if
and a call to getOption
.
Upvotes: 6
Reputation: 23114
Just for the record, here is what I came up with after reading @G.Grothendieck 's answer:
dbgexec = function(cmd) {
command = substitute(cmd)
if(getOption("mypack.debug", FALSE)) eval(cmd, parent.frame())
invisible(NULL)
}
Example:
> 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
And an experiment with @flodel's answer:
> 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
Upvotes: -1
Reputation: 89067
Another option would be to define a debugging
function in your package:
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
This should solve your concern about "What if I decide to change the package name later?" I suppose.
Upvotes: 4