无论是在包装中还是偶尔在基础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中的调用和后期绑定有何了解,那么这将失败(无限递归)。
有没有办法实现这一点(本着面向对象的功能覆盖的精神),而不诉诸
这是否有范例?或者我怎样才能以最安全的方式解决这个问题?或者我只是希望得到太多?
编辑鉴于@Andrie的回答:这可以很简单地完成。但是,如果我想改变包中另一个函数调用的包中某些函数的行为,Andrie的技巧将无效。
作为一个例子:我对glmnet
包的绘图功能做了很多补充。但是如果你看一下plot.cv.glmnet
之类的东西,你会看到他们将调用转发给该包中的另一个函数,所以我真的需要将我的新版本注入到包中(顺便说一下,可以使用reassignInPackage
)完成。但当然命名空间前缀将失败,因为我刚刚更换了命名空间版本。这个例子并不像看起来那样做作:我去过那里很多次。另一方面,也许有人会/我可以争辩说我应该放弃我的要求吗?那将是最好的方式呢?
答案 0 :(得分:7)
如果我理解正确,我认为引用namespace::function
是一件简单的事情,即在这种情况下在你的函数中使用base::cat
。
例如:
cat <- function(... , file = "", sep = " ", fill = FALSE, labels = NULL,
append = FALSE)
{
base::cat(..., "\n" , file = file, sep = sep, fill = fill, labels = labels,
append = append)
}
> cat("Hello", "world!")
Hello world!
> cat("Text on line 2")
Text on line 2