這是一個單線程,它可以做到這一點。這裏的PackageFuncA
是stats::acf
和PackageFuncB
是我們想用my.plot.acf
替換的stats:::plot.acf
。 my.plot.acf
打印"Hello"
然後調用真實的stats:::plot.acf
。
# we want this to run in place of stats:::plot.acf
my.plot.acf <- function(x, ...) { cat("Hello\n"); stats:::plot.acf(x, ...) }
# this does it
library(proto)
acf <- with(proto(environment(acf), acf = stats::acf, plot.acf = my.plot.acf), acf)
# test
acf(1:10)
甲原對象是這樣的環境,其經由proto
功能插入到對象的任何功能都有它的環境自動地復位到該對象。 proto()
的第一個參數是原始對象的父項。
在上面的例子中,它的設置使得acf
變量引用插入到proto對象中的版本acf
(除了原來的對象被修改爲原始對象之外,它與原始對象相同)。當運行新的acf
函數時plot.acf
是一個自由變量(即,未在acf
中定義),因此它在acf
的父級中查找,並且它是原始對象中的環境,它在其中找到新的plot.acf
。 acf
可能有其他自由變量,但在這些情況下,因爲它們在原始對象中未找到,它將查看原始對象的父級,原始對象是原始的acf
的原始環境。在圖方面,我們有這個地方<-
意味着左側是右側的父:
environment(stats::acf) <- proto object <- revised acf
與原對象既包含plot.acf
和修訂後的acf
。
我們還將新的plot.acf
的環境設置爲原始對象。我們可能需要也可能不需要這樣做。在很多情況下,這並不重要。如果它是重要的是不要設置新plot.acf
那就這樣做的環境,因爲原不落的插入功能使用[[...]]
環境:
acf <- with(p <- proto(environment(acf), acf = stats::acf), acf)
p[["plot.acf"]] <- my.plot.acf
在這個例子中,這兩種方法的工作。
這將有可能做這一切與平原環境下,在不必使用幾行代碼的代價:
# create new environment whose parent is the original acf's parent
e <- new.env(parent = environment(stats::acf))
# the next statement is only need to overwrite any acf you already might have from
# trying other code. If you were sure there was no revised acf already defined
# then the next line could be omitted. Its a bit safer to include it.
acf <- stats::acf
# This sets the environment of the new acf. If there were no acf already here
# then it would copy it from stats::acf .
environment(acf) <- e
# may or may not need next statement. In this case it doesn't matter.
environment(my.plot.acf) <- e
e$plot.acf <- my.plot.acf
acf(1:10)
在這種情況下,我們沒有下過修訂acf
在e
作爲原例如,但只設置其父。事實上,將修訂的acf
納入e
或原始對象並非絕對必要,但僅在原始案例中完成,因爲原型具有重置環境的副作用,並且是我們之後的副作用。另一方面,有必要將修改後的plot.acf
放在e
或原始對象中,以便在原始對象之前遇到它。
您可能想要閱讀此paper,特別是第21頁開始的代理部分,因爲此處顯示的技術是代理對象的示例。
創建自己的PackageFunA並更改對PackageFunB的調用以便它調用您的函數會更容易嗎? – joran
請參閱'?assignInNamespace' – Andrie
joran - 我寧願不維護自己的PackageFuncA版本,特別是因爲它不僅僅是幾行代碼。 – SFun28