【发布时间】:2011-12-25 23:52:03
【问题描述】:
无论是在包中还是偶尔在基础 R 中,我有时都想为现有函数添加一点味道。大多数情况下,这只是函数开头或结尾处应该发生的事情的微小变化(愚蠢的例子:我希望 cat 函数默认在末尾包含换行符)。
现在我知道我可以通过将我的新实现分配给它的名称来简单地覆盖现有方法,但是:那么,我仍然可以使用旧方法吗?对于cat,我将不得不这样做:
cat<-function(... , file = "", sep = " ", fill = FALSE, labels = NULL,
append = FALSE)
{
cat(..., "\n" , file = file, sep = sep, fill = fill, labels = labels,
append = append)
}
这意味着在新的实现中使用'旧'cat。现在,如果我了解 R 中的调用和后期绑定是如何工作的,这将简单地失败(无限递归)。
那么有没有办法实现这一点(本着面向对象的函数覆盖精神),而不诉诸
- 为我的新函数命名(我希望它“正常工作”)
- 以其他名称保存旧函数(然后,当我创建 这个函数在另一个 R 会话中,我可能会忘记额外的步骤)
- 使用原始函数的所有源代码(正如@Andrie 所说:拥有尽可能优雅的解决方案很重要)
有这方面的范例吗?或者我怎么能以最安全的方式解决这个问题?还是我的愿望太多了?
编辑 鉴于@Andrie 的回答:这可以很简单地完成。但是,如果我想改变包中的某个函数的行为,而该包中的另一个函数调用了该函数,那么 Andrie 的技巧将不起作用。
例如:我对glmnet 包的绘图功能做了很多补充。但是,如果您查看plot.cv.glmnet 之类的,您会看到他们将调用转发到该包中的另一个函数,所以我真的需要将我的新版本注入包中(顺便说一下,可以用reassignInPackage完成)。但是当然命名空间前缀会失败,因为我刚刚替换了命名空间版本。这个例子并不像看起来那么做作:我去过那里很多次。另一方面,也许有人会/可以争辩说在这种情况下我应该放弃我的要求?那么哪种方式最好呢?
【问题讨论】: