假设我替换了一个包的功能,例如knitr:::sub_ext
. (注意:我对它是一个内部函数特别感兴趣,即只能通过:::
而不是 访问::
,但相同的答案可能对两者都有效)。
library(knitr)
my.sub_ext <- function (x, ext) {
return("I'm in your package stealing your functions D:")
}
# replace knitr:::sub_ext with my.sub_ext
knitr <- asNamespace('knitr')
unlockBinding('sub_ext', knitr)
assign('sub_ext', my.sub_ext, knitr)
lockBinding('sub_ext', knitr)
问题:完成此操作后有什么方法可以检索原件? knitr:::sub_ext
最好不重新加载包?
(我知道有些人想知道我为什么要这样做,所以就在这里。这个问题不需要阅读)。我一直在修补软件包中的一些功能(实际上不是sub_ext
功能......):
original.sub_ext <- knitr:::sub_ext
new.sub_ext <- function (x, ext) {
# some extra code that does something first, e.g.
x <- do.something.with(x)
# now call the original knitr:::sub_ext
original.sub_ext(x, ext)
}
# now set knitr:::sub_ext to new.sub_ext like before.
我同意这通常不是一个好主意(在大多数情况下,这些都是快速修复,直到更改进入 CRAN,或者它们是永远不会被批准的“功能请求”,因为它们在某种程度上是特定于案例的)。
上面的问题是,如果我不小心执行了两次(例如,它在我运行两次的脚本的顶部,中间没有重新启动 R),第二次original.sub_ext
实际上是前一次new.sub_ext
而不是真正的 knitr:::sub_ext
,所以我得到无限递归。
由于sub_ext
是一个内部函数(我不会直接调用它,但是来自 knitr 的函数knit
都像内部调用它一样),我不能希望修改所有sub_ext
调用new.sub_ext
手动调用的函数,因此替换定义中的方法包命名空间。