Отладка общих функций в R

Как вы отлаживаете общую функцию (используя debug или mtrace в пакете отладки)?

В качестве примера я хочу отладить cenreg в пакете NADA, в частности метод, который принимает ввод формулы.

Вы можете получить данные метода следующим образом:

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")

Я не знаю, как выполнить основной метод, а не общую оболочку.

Ответ 1

Мои первые два предложения довольно простые: (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 классы могут быть трудными для работы; одним из примеров этого является комментарий в документации debug (относительно использования mtrace() с классами S4):

"I have no plans to write S4 methods, and hope not to have to
debug other people’s!"

A аналогичный вопрос был задан недавно в 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.

Кстати, вы можете использовать зеркало CRAN NADA в github для просмотра источника.

Ответ 2

Долгое время это была стандартная проблема для отладки метода S4. Как указал Чарльз Плесси, я работал с Майклом Лоуренсом над добавлением в R ряда функций, призванных облегчить это.

debug, debugonce, undebug и isdebugged теперь все принимают аргумент подписи, подходящий для определения методов s4. Кроме того, при отладке методов S4 таким способом обходятся странные детали реализации, с которыми вам ранее приходилось сталкиваться вручную, путем browser в методе через trace, .local определения .local, отладки, а затем продолжения.

Кроме того, я добавил debugcall, который вы фактически выполняете, полный вызов, который вы хотели бы вызвать. Это устанавливает отладку в первом закрытии, которое будет вызываться при оценке этого вызова, который не является стандартным обобщением S3 или S4. Таким образом, если вы вызываете неуниверсальный, это будет просто вызываемая функция верхнего уровня, но если это стандартный универсальный S3 или S4, первый отработанный метод будет отлажен вместо универсального. "Стандартный универсальный S3" определяется как функция, в которой первый вызов верхнего уровня (без учета фигурных скобок) в теле является вызовом UseMethod.

Обратите внимание, что мы пошли туда-сюда по дизайну этого, но в конце дня остановились на debugcall фактически не выполняет отлаживаемый вызов функции, но он возвращает выражение вызова, которое вы можете передать его eval если хотите, как показано в ?debugcall.