我希望能够在逐个函数级别上控制是否通过R函数打印详细的调试信息。通过检查全局变量(What's similar to an #ifdef DEBUG in R?)可以通过多种方式实现此目的,但我希望能够与R的现有trace
功能集成。我还没有找到一种方法来确定一个函数是否正在跟踪它。
我设想这样的事情:
> f = function(x) {
+ tracePrint("x is ", x)
+ x
+ }
> f(1)
[1] 1
>
> trace(f)
> f(1)
trace: f(1)
x is 1
[1] 1
> untrace(f)
> f(1)
[1] 1
>
有没有办法编写一个tracePrint()函数,在跟踪调用者时打印参数,但不执行任何操作?
我很乐意接受一个" if(traced())print(x)"语法如果这更容易,但绝对需要一个通过trace()/ untrace()完成控制的系统,并且这些系统的额外功能仍可单独使用。
我想我可以重新定义这些以在由函数名称(或者函数本身的属性?)索引的全局中设置标志,但似乎应该有更优雅的方法来实现这一点。
答案 0 :(得分:2)
更传统的方法是使用类似futile.logger的内容。
我不知道有什么可用的东西,但是在功能被标记为'被跟踪'的方式中略微戳了一下,导致C单线程测试是否正在跟踪某个功能
library(inline)
isTracing = cfunction(signature(fun="function"), body="
return Rf_ScalarLogical(RTRACE(fun) ? TRUE : FALSE);
")
用作
> f = function(x) x
> isTracing(f)
[1] FALSE
> trace(f)
> isTracing(f)
[1] TRUE
在关闭全局跟踪状态时,可能需要使用isTracing(f) && tracingState()
来捕获这种情况。
这可以用于至少一些eval(sys.call()[[1]])
的函数调用(我不知道这是否是识别被调用函数的好方法),例如,
f = function() g()
g = function() isTracing(eval(sys.call()[[1]]))
使用中:
> f()
[1] FALSE
> trace(g)
> f()
[1] TRUE
变得越来越hacky,似乎trace()
使用从“traceable”类派生的类来将函数/泛型/方法标记为被跟踪。所以测试可能是
tracing <- function(fun)
tracingState() && (is(fun, "traceable") || isTracing(fun))
与
g = function() tracing(eval(sys.call()[[1]]))
(某些)方法失败
.A = setClass("A", "list")
setGeneric("foo", function(x) standardGeneric("foo"))
setMethod("foo", "A", function(x) tracing(eval(sys.call()[[1]])))
trace("foo", signature="A")
foo(.A()) # returns FALSE instead of TRUE
因为eval(sys.call()[[1]])
获得通用而非方法