我希望能够逐个函数级别控制 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() 完成控制的系统,并且这些的额外功能仍然可以单独使用。
在紧要关头,我想我可以重新定义它们,在按函数名称索引的全局中设置一个标志(或者可能是函数本身的属性?),但似乎应该有一种更优雅的方法来完成此操作。
最佳答案
更传统的方法是使用类似 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]])
获取的是泛型而不是方法
关于r - 检查 R 函数是否正在被跟踪?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28511586/