Overwrite method to extend it, using the original implementation

蓝咒 提交于 2019-12-04 05:45:53

问题


Whether in a package or occasionally in base R, I sometimes want to add a little flavor to an existing function. Most of the times, this is a minor change of what should happen at the start or at the end of the function (silly example: I'd like the cat function to include a newline at the end by default).

Now I know I can simply overwrite an existing method by assigning my new implementation to its name, BUT: how, then, can I still use the old one? In the case of cat, I would have to do something like:

cat<-function(... , file = "", sep = " ", fill = FALSE, labels = NULL,
    append = FALSE)
{
  cat(..., "\n" , file = file, sep = sep, fill = fill, labels = labels,
    append = append)
}

This means using the 'old' cat in the implementation of the new one. Now if I understand anything about how calling and late binding in R work, this will simply fail (infinite recursion).

So is there a way of achieving this (in the spirit of object-oriented overrides of functions), without resorting to

  • giving my new function another name (I want it to 'just work')
  • saving the old function under some other name (Then, when I create this function in another R session, I might forget the extra step)
  • using all the source of the original function (As @Andrie said: it is important to have the most elegant solution possible)

Is there a paradigm for this? Or how could I go about this in the safest way possible? Or am I just wishing for too much?

Edit Given @Andrie's answer: this can be done quite simply. However, Andrie's trick will not work if I want to alter the behaviour of some function in a package that is called by another function in the package.

As an example: I have made numerous additions to the plotting functions of the glmnet package. But if you look at plot.cv.glmnet and the likes, you will see that they forward the call to another function within that package, so I'd really need to inject my new version into the package (which, by the way, can be done with reassignInPackage). But then of course the namespace prefixing will fail because I've just replaced the namespaced version. This example is not as contrived as it might seem: I've been there quite a few times. On the other hand, maybe somebody will/can argue that I should drop my requirements in that case? Which would be the best way to go then?


回答1:


If I understand you correctly, I think it's a simple matter of referring to namespace::function, i.e. in this case use base::cat inside your function.

For example:

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 


来源:https://stackoverflow.com/questions/8077003/overwrite-method-to-extend-it-using-the-original-implementation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!