假设有一组函数,是从我写的软件包中绘制的,我想分配给错误的特殊行为。我目前的关注是_impl在dplyr中的功能家族。以mutate_impl为例。当我从突变中遇到错误时,反驳几乎总是会导致我突变_impl,但通常是呼叫堆栈的一种方式 - 我看到它是从通话中进行突变的15个呼叫。因此,我想知道的是,通常是如何与我最初提供的参数相关的论点是如何相关的(或认为我做到的(。
因此,此代码在数量上可能是错误的 - 当然它不起作用 - 但我希望它至少有助于表达我的意图。这个想法是我可以将其包裹在mutate_impl上,如果它产生了错误,它将保存错误消息和参数的描述,并将它们返回为列表
str_impl <- function(f){tryCatch(f, error = function(c) {
msg <- conditionMessage(c)
args <- capture.output(str(as.list(match.call(call(f)))))
list(message = msg, arguments = args)
}
assign(str_impl(mutate_impl), .GlobalEnv)
尽管这仍然没有我想要的东西,因为即使没有工作代码的限制,我也无法弄清楚如何生产草稿。我真正想要的是能够识别我想在错误上具有此行为的函数或列表,然后在调用该函数的任何地方都会出现错误。我想不出任何方法可以在不重新写入dplyr包装环境中的功能的情况下开始这样做,这让我感到非常糟糕。
即使对Mutate_impl的调用发生在某个地方,甚至在错误之后不再存在的环境中,也应该将错误对象带回我可以找到的某个地方,甚至应该将错误对象恢复到我可以找到的地方。
可能是通过trace
功能实现所需的最佳方法。肯定值得阅读有关trace
的帮助,但这是一个有效的例子:
library(dplyr)
trace("mutate_impl", exit = quote({
if (class(returnValue())[1]=="NULL") {
cat("dfn")
print(head(df))
cat("nndotsn")
print(dots)
} else {
# no problem, nothing to do
}
}), where = mutate, print = FALSE)
# ok
xx <- mtcars %>% mutate(gear = gear * 2)
# not ok, extra output
xx <- mtcars %>% mutate(gear = hi * 2)
根据您的特定需求进行调整应该非常简单,例如如果要登录到文件而不是:
trace("mutate_impl", exit = quote({
if (class(returnValue())[1]=="NULL") {
sink("error.log")
cat("dfn")
print(head(df))
cat("nndotsn")
print(dots)
sink()
} else {
# no problem, nothing to do
}
}), where = mutate, print = FALSE)