检查R函数是否被跟踪?

时间:2015-02-14 01:51:13

标签: r debugging trace

我希望能够在逐个函数级别上控制是否通过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()完成控制的系统,并且这些系统的额外功能仍可单独使用。

我想我可以重新定义这些以在由函数名称(或者函数本身的属性?)索引的全局中设置标志,但似乎应该有更优雅的方法来实现这一点。

1 个答案:

答案 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]])获得通用而非方法