使用原始实现覆盖扩展它的方法

时间:2011-11-10 08:58:20

标签: r overwrite

无论是在包装中还是偶尔在基础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)完成。但当然命名空间前缀将失败,因为我刚刚更换了命名空间版本。这个例子并不像看起来那样做作:我去过那里很多次。另一方面,也许有人会/我可以争辩说我应该放弃我的要求吗?那将是最好的方式呢?

1 个答案:

答案 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