trace
位于 base
包(package)。 说明
调用trace
允许您插入调试代码(例如,调用browser
或者recover
)在任何函数中的选定位置。调用untrace
取消追踪。可以以相同的方式跟踪指定的方法,而无需跟踪对通用函数的所有调用。跟踪代码(tracer
) 可以是任何R表达。可以通过调用全局暂时打开或关闭跟踪tracingState
.
用法
trace(what, tracer, exit, at, print, signature,
where = topenv(parent.frame()), edit = FALSE)
untrace(what, signature = NULL, where = topenv(parent.frame()))
tracingState(on = NULL)
.doTrace(expr, msg)
returnValue(default = NULL)
参数
what |
要跟踪或不跟踪的函数的名称,可能是 |
tracer |
function 或未计算的表达式。将在调用开始时或在参数 |
exit |
|
at |
可选的数字向量或列表。如果提供, |
print |
如果 |
signature |
如果提供此参数,它应该是函数 |
edit |
对于复杂的跟踪,例如在函数内的循环内进行跟踪,您将需要通过编辑函数体来插入所需的调用。如果是这样,请将 |
where |
在哪里寻找要跟踪的函数;默认情况下,调用 此参数的一个重要用途是跟踪 “hidden” 包中的函数或从另一个包调用的函数。命名空间机制导入要调用的函数(基础包中的函数除外)。被调用的函数是不是从顶层看到的相同对象(通常,导入的包甚至可能不附加)。因此,您必须确保跟踪正确的版本。做到这一点的方法是设置参数 |
on |
逻辑性;如果全局打开跟踪,则对支持函数 |
expr, msg |
支持函数 |
default |
如果 |
细节
trace
函数通过构造函数(或方法,如果提供了 signature
)的修订版本来运行,并将新对象分配回原始对象所在的位置。如果仅给出 what
参数,则每次调用该函数都会生成一行跟踪打印(向后兼容 trace
的早期版本)。
trace
构造的对象来自扩展"function"
的类,其中包含原始的、未跟踪的版本。调用 untrace
会重新分配此版本。
如果参数 tracer
或 exit
是函数名称,则跟踪表达式将是对该函数的调用,不带参数。这是最简单和最常见的情况,函数 browser
和 recover
是最有可能的候选者;前者在被跟踪的函数框架中浏览,后者允许在任何当前活动的调用中浏览。对参数 tracer
和 exit
进行评估以查看它们是否是函数,但在跟踪表达式中仅使用它们的名称。当跟踪函数执行时会再次进行查找,因此跟踪时可能不会调用tracer
或exit
。
tracer
或 exit
参数也可以是未计算的表达式(例如通过调用 quote
或 substitute
返回)。该表达式本身插入到跟踪函数中,因此它通常会涉及跟踪函数中的参数或本地对象。如果您只想在某些条件适用时进行交互,则这种形式的表达式非常有用(在这种情况下,您可能还想在对 trace
的调用中提供 print = FALSE
)。
当提供 at
参数时,它可以是引用函数体子步骤的整数向量(仅当函数体包含在 { ...}
中时才有效)。在这种情况下,tracer
不会在进入时调用,而是在评估 at
中列出的每个步骤之前调用。 (提示:您不想尝试计算函数打印版本中的步骤;相反,请查看 as.list(body(f))
以获取与函数 f
中的步骤关联的数字。)
at
参数也可以是整数向量列表。在这种情况下,每个向量引用函数的另一个步骤中嵌套的一个步骤。例如,at = list(c(3,4))
将在函数第三步的第四步之前调用跟踪器。请参阅下面的示例。
使用 setBreakpoint
(来自包 utils
)可能是一种替代方法,调用 trace(...., at, ...)
。
exit
参数在 on.exit
处理期间调用。在on.exit
表达式中,可以调用实验returnValue()
函数来获取该函数将要返回的值。在其他情况下调用此函数将给出未定义的结果。
exit
参数的一个内在限制是,如果函数本身使用 on.exit
和 add=
FALSE
(默认),它将不起作用,因为现有调用将覆盖 trace
提供的调用。
跟踪不嵌套。对 trace
的任何调用都会替换该函数或方法之前跟踪的版本(除了下面讨论的编辑版本),并且 untrace
始终恢复未跟踪的版本。 (允许嵌套跟踪很可能会造成混乱,并且可能会意外留下跟踪版本。)
当重复使用 edit
参数且中间没有在同一函数或方法上调用 untrace
时,将保留先前编辑的版本。如果您想丢弃所有先前的跟踪然后进行编辑,请在下次调用 trace
之前调用 untrace
。编辑可与自动跟踪相结合;只需提供其他参数,例如 tracer
和 edit
参数。 edit = TRUE
参数使用默认编辑器(请参阅 edit
)。
从基础包中跟踪原始函数(内置函数和特殊函数)是可行的,但只能通过特殊机制进行,并且信息量不大。跟踪原语会导致原语被带有参数的函数替换...(仅)。你可以得到一些信息,但不多。当在原语上使用 trace
时,会发出警告消息。
将函数的跟踪版本保存回函数来源的位置的做法意味着,如果跟踪函数保存在会话映像中,则跟踪会从一个会话转移到另一个会话。 (在下一个会话中,untrace
将删除跟踪。)另一方面,包中而不是全局环境中的函数不会保存在映像中,因此跟踪会随着此类函数的会话而过期。
跟踪 S4 方法本质上就像跟踪函数一样,不同之处在于跟踪版本是通过调用 setMethod
而不是直接赋值来存储的,调用 untrace
后的未跟踪版本也是如此。
的版本trace
这里说明的在很大程度上与S-Plus中的版本兼容,尽管两者的工作机制完全不同。 S-Plustrace
使用会话框架,其结果是跟踪永远不会从一个会话转移到另一个会话(R没有会话框架)。另一个相关的区别与以下内容没有直接关系trace
:S-Plus中的浏览器允许对正在浏览的框架进行更改,并且退出浏览器后更改将保留。这R浏览器允许更改,但当浏览器退出时它们就会消失。这可能是相关的,因为 S-Plus 版本允许您交互地试验代码更改,但是R版本没有。 (未来的修订版可能包括 ‘destructive’ 浏览器R.)
值
在简单版本中(仅第一个参数), trace
返回不可见的 NULL
。否则,为跟踪的函数名称。相关的结果是发生的分配。
untrace
不可见地返回函数名称。
tracingState
返回当前全局跟踪状态,并可能更改它。
在 on.exit
处理期间调用时,returnValue
返回退出函数即将返回的值。其他情况下的行为未定义。
注意
使用 trace()
在概念上是 debug
的泛化,但实现方式不同。即通过tracer
或exit
参数调用browser
。
包含除函数名称之外的任何参数的函数跟踪版本需要 methods
包(因为它使用特殊的对象类来存储和恢复跟踪函数的版本)。
如果当前未启用方法调度,trace
将加载方法命名空间,但不会将方法包放在 search
列表中。
例子
require(stats)
## Very simple use
trace(sum)
hist(rnorm(100)) # shows about 3-4 calls to sum()
untrace(sum)
## Show how pt() is called from inside power.t.test():
if(FALSE)
trace(pt) ## would show ~20 calls, but we want to see more:
trace(pt, tracer = quote(cat(sprintf("tracing pt(*, ncp = %.15g)\n", ncp))),
print = FALSE) # <- not showing typical extra
power.t.test(20, 1, power=0.8, sd=NULL) ##--> showing the ncp root finding:
untrace(pt)
f <- function(x, y) {
y <- pmax(y, 0.001)
if (x > 0) x ^ y else stop("x must be positive")
}
## arrange to call the browser on entering and exiting
## function f
trace("f", quote(browser(skipCalls = 4)),
exit = quote(browser(skipCalls = 4)))
## instead, conditionally assign some data, and then browse
## on exit, but only then. Don't bother me otherwise
trace("f", quote(if(any(y < 0)) yOrig <- y),
exit = quote(if(exists("yOrig")) browser(skipCalls = 4)),
print = FALSE)
## Enter the browser just before stop() is called. First, find
## the step numbers
untrace(f) # (as it has changed f's body !)
as.list(body(f))
as.list(body(f)[[3]]) # -> stop(..) is [[4]]
## Now call the browser there
trace("f", quote(browser(skipCalls = 4)), at = list(c(3,4)))
## Not run:
f(-1,2) # --> enters browser just before stop(..)
## End(Not run)
## trace a utility function, with recover so we
## can browse in the calling functions as well.
trace("as.matrix", recover)
## turn off the tracing (that happened above)
untrace(c("f", "as.matrix"))
## Not run:
## Useful to find how system2() is called in a higher-up function:
trace(base::system2, quote(print(ls.str())))
## End(Not run)
##-------- Tracing hidden functions : need 'where = *'
##
## 'where' can be a function whose environment is meant:
trace(quote(ar.yw.default), where = ar)
a <- ar(rnorm(100)) # "Tracing ..."
untrace(quote(ar.yw.default), where = ar)
## trace() more than one function simultaneously:
## expression(E1, E2, ...) here is equivalent to
## c(quote(E1), quote(E2), quote(.*), ..)
trace(expression(ar.yw, ar.yw.default), where = ar)
a <- ar(rnorm(100)) # --> 2 x "Tracing ..."
# and turn it off:
untrace(expression(ar.yw, ar.yw.default), where = ar)
## Not run:
## trace calls to the function lm() that come from
## the nlme package.
trace("lm", where = asNamespace("nlme"))
lm (len ~ log(dose) * supp, ToothGrowth) -> fit1 # NOT traced
nlme::lmList(len ~ log(dose) | supp, ToothGrowth) -> fit2 # traced
untrace("lm", where = asNamespace("nlme"))
## End(Not run)
参考
Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988) The New S Language. Wadsworth & Brooks/Cole.
也可以看看
browser
和 recover
,最有可能的跟踪函数;另外,quote
和 substitute
用于构造通用表达式。
相关用法
- R tracemem 对象的跟踪复制
- R traceback 获取并打印调用堆栈
- R transform 转换对象,例如 DataFrame
- R try 尝试允许错误恢复的表达式
- R trimws 删除前导/尾随空格
- R taskCallback 添加或删除顶级任务回调
- R toString 将 R 对象转换为字符串或测试字符串
- R tilde 波形符运算符
- R textConnection 文本连接
- R t 矩阵转置
- R table 交叉表和表格创建
- R tempfile 为临时文件创建名称
- R taskCallbackManager 创建R级任务回调管理器
- R typeof 对象的类型
- R taskCallbackNames 查询当前内部顶级任务回调名称
- R timezones 时区
- R tabulate 向量列表
- R tapply 对不规则数组应用函数
- R file.path 构造文件路径
- R grep 模式匹配和替换
- R getwd 获取或设置工作目录
- R vector 向量 - 创建、强制等
- R lapply 对列表或向量应用函数
- R dump R 对象的文本表示
- R Sys.getenv 获取环境变量
注:本文由纯净天空筛选整理自R-devel大神的英文原创作品 Interactive Tracing and Debugging of Calls to a Function or Method。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。