如何调试泛型函数(在调试包中使用debug或mtrace)?
作为一个例子,我想在NADA包中调试cenreg,特别是采用公式输入的方法。
您可以像这样检索方法详细信息:
library(NADA)
getMethod("cenreg", c("formula", "missing", "missing"))
function (obs, censored, groups, ...)
{
.local <- function (obs, censored, groups, dist, conf.int = 0.95,
...)
{
dist = ifelse(missing(dist), "lognormal", dist)
...
}
问题是cenreg本身看起来像这样:
body(cenreg)
# standardGeneric("cenreg")
我不知道如何单步执行底层方法,而不是通用包装器。
答案 0 :(得分:14)
我的前两个建议非常基本:(1)将函数调用包装在try()
中(经常提供有关S4类的更多信息)和(2)在抛出错误后调用traceback()
(有时可以提示问题真正发生的地方)。
在此方案中调用debug()
无效,因此您需要使用trace
或browser
。从调试帮助页面:
"In order to debug S4 methods (see Methods), you need to use trace, typically
calling browser, e.g., as "
trace("plot", browser, exit=browser, signature = c("track", "missing"))
S4课程很难使用;一个例子是the debug
package文档中的注释(关于mtrace()
与S4类的用法):
"I have no plans to write S4 methods, and hope not to have to
debug other people’s!"
A similar question was asked recently on R-Help。邓肯默多克的建议:
"You can insert a call to browser() if you want to modify the source. If
you'd rather not do that, you can use trace() to set a breakpoint in it.
The new setBreakpoint() function in R 2.10.0 will also work, if you
install the package from source with the R_KEEP_PKG_SOURCE=yes
environment variable set. It allows you to set a breakpoint at a
particular line number in the source code."
我之前从未这样做过(它需要R 2.10.0),但您可以尝试使用R_KEEP_PKG_SOURCE=yes
从源代码安装。
顺便说一句,您可以使用github中的CRAN mirror of NADA来浏览源代码。
答案 1 :(得分:0)
很长一段时间以来,这一直是S4方法调试的标准麻烦点。正如查尔斯·普莱西(Charles Plessy)所指出的那样,我与迈克尔·劳伦斯(Michael Lawrence)一起为R添加了许多功能,旨在简化此操作。
debug
,debugonce
,undebug
和isdebugged
现在都采用了适合指定s4方法的签名参数。此外,以这种方式调试S4方法会绕过您以前必须手动处理的怪异的实现细节,方法是通过browser
trace
进入方法,逐步执行.local
定义,然后调试,然后继续。
此外,我添加了debugcall
,您将对其进行实际,完整的调用。这样做可以设置第一个关闭消息的调试,在评估不是S3或S4标准泛型的调用时将调用该消息。因此,如果您要调用的是非泛型函数,那将只是被调用的顶级函数,但是如果它是标准的S3或S4泛型函数,则将调试的第一个 method 调试为而不是通用。 “标准的S3泛型”定义为一种函数,其中主体中的第一个顶级(忽略花括号)调用是对UseMethod的调用。
请注意,我们在此设计上来回走动,但最终还是以debugcall
为依据。不是实际上是在执行正在调试的函数调用,但它会返回调用表达式您可以根据需要将其传递给eval
,如?debugcall
所示。