调试R中的泛型函数

Ric*_*ton 12 debugging r

如何调试泛型函数(在调试包中使用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)

...
}
Run Code Online (Sandbox Code Playgroud)

问题是cenreg本身看起来像这样:

body(cenreg)
# standardGeneric("cenreg")
Run Code Online (Sandbox Code Playgroud)

我不知道如何单步执行底层方法,而不是通用包装器.

Sha*_*ane 14

我的前两个建议非常基本:(1)将函数调用包装在try()(通常用S4类提供更多信息)和(2)traceback()抛出错误后调用(有时可以提示问题实际发生的位置) ).

debug()在这种情况下,调用无济于事,因此您需要使用tracebrowser.从调试帮助页面:

"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")) 
Run Code Online (Sandbox Code Playgroud)

S4课程很难处理; 这样的一个例子是在注释debug文件(关于使用mtrace()与S4类):

"I have no plans to write S4 methods, and hope not to have to
debug other people’s!"
Run Code Online (Sandbox Code Playgroud)

一个类似的问题是对R-帮助最近询问.邓肯默多克的推荐:

"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."
Run Code Online (Sandbox Code Playgroud)

我以前从未这样做过(它需要R 2.10.0),但你可以尝试从源码安装R_KEEP_PKG_SOURCE=yes.

顺便提一下,您可以在github中使用NADACRAN镜像来浏览源代码.

  • 引用R 3.4.0的[发行说明](https://cran.r-project.org/doc/manuals/r-release/NEWS.html),`signature`参数被添加到`debug()` ,`debugonce()`,`undebug()`和`isdebugged()`用于更方便地调试S3和S4方法.(基于Gabe Becker的补丁.) (4认同)

Gab*_*ker 10

长期以来,这是 S4 方法调试的标准烦恼点。正如 Charles Plessy 所指出的那样,我与 Michael Lawrence 合作为 R 添加了许多功能,旨在使这变得更容易。

debug, debugonce,undebugisdebugged现在都采用适合指定 s4 方法的签名参数。此外,以这种方式调试 S4 方法绕过了您以前必须手动处理的奇怪的实现细节,browser方法是通过 进入方法trace,逐步完成.local定义,调试,然后继续。

此外,我添加了debugcall,您给出了一个您想要调用的实际完整调用。这样做会在第一个关闭时设置调试,在评估不是 S3 或 S4 标准 generic 的调用时将调用关闭。因此,如果您正在调用非泛型,那将只是被调用的顶级函数,但如果它是标准的 S3 或 S4 泛型,则会调试将命中的第一个方法而不是泛型。“标准 S3 泛型”被定义为一个函数,其中主体中的第一个顶级(忽略大括号)调用是对 UseMethod 的调用。

请注意,我们在此设计上来回反复,但最终决定debugcall 实际执行正在调试的函数调用,但它返回调用表达式,eval如果需要,您可以将其传递给它,如 中所示?debugcall