无论是在包装中还是偶尔在基础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)
}
Run Code Online (Sandbox Code Playgroud)
这意味着cat在新实现中使用"旧" .现在,如果我对R中的调用和后期绑定有何了解,那么这将失败(无限递归).
那么有没有办法实现这一点(本着面向对象的功能覆盖的精神),而不是诉诸于此
有这样的范例吗?或者我怎样才能以最安全的方式解决这个问题?或者我只是想要太多?
编辑 @Andrie的回答:这可以很简单地完成.但是,如果我想改变包中另一个函数调用的包中某些函数的行为,Andrie的技巧将无效.
举个例子:我对glmnet包的绘图功能做了很多补充.但是如果你看看plot.cv.glmnet和喜欢,你会看到他们将调用转发到该包中的另一个函数,所以我真的需要将我的新版本注入到包中(顺便说一下,可以完成reassignInPackage) .但当然命名空间前缀将失败,因为我刚刚更换了命名空间版本.这个例子并不像看起来那样做作:我去过那里很多次.另一方面,也许有人会/我可以争辩说我应该放弃我的要求吗?那将是最好的方式呢?
如果我理解正确,我认为这是一个简单的引用问题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
Run Code Online (Sandbox Code Playgroud)