これは、これを行う1つのライナーです。ここでPackageFuncA
はstats::acf
であり、PackageFuncB
はと置き換えたい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()
の最初の引数はprotoオブジェクトの親です。
上記の例では、acf
という変数がprotoオブジェクトに挿入されたacf
のバージョンを参照するように設定されています(これは、その環境がprotoオブジェクトに変更されていることを除いて)。新しいacf
関数が実行されると、plot.acf
は空き変数(acf
で定義されていない)なので、acf
の親で参照され、それは新しいplot.acf
が見つかるprotoオブジェクトの環境です。 acf
には他のフリー変数が含まれているかもしれませんが、protoオブジェクトに見つからないため、オリジナルの元の環境であるprotoオブジェクトの親を調べますacf
。
environment(stats::acf) <- proto object <- revised acf
とプロトオブジェクトがplot.acf
と改訂acf
の両方が含まれています。図の面では、我々は<-
が左サイドを意味し、これは右側の親である必要があります。
また、新しいplot.acf
の環境をprotoオブジェクトに設定しました。私たちはこれをする必要があってもいなくてもよいでしょう。多くの場合、それは重要ではありません。この例では
acf <- with(p <- proto(environment(acf), acf = stats::acf), acf)
p[["plot.acf"]] <- my.plot.acf
、両方の仕事に近づく:それは新しいplot.acf
の環境を設定しないことが重要だった場合、それがprotoは[[...]]
を使用して挿入機能の環境を設定したことがないので、次のように行われます。
数行のコードを使用することを犠牲にしてプレーンな環境でこのすべてを行うことが可能であろう:私たちはプロトのようにe
に改定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
またはprotoオブジェクトに配置することは厳密には必要ではありませんが、protoの場合は環境を再設定するという副作用があり、その後の副作用があったため、protoの場合のみ実行されました。一方、修正されたplot.acf
をe
またはprotoオブジェクトに置き、元のオブジェクトに先立って遭遇するようにする必要があります。
paperを参照してください。ここで示すテクニックはプロキシオブジェクトの例であるため、特にプロキシ開始ページ21を参照してください。
独自のPackageFunAを作成し、代わりに関数を呼び出すようにPackageFunBの呼び出しを変更する方が簡単でしょうか? – joran
'?assignInNamespace'を参照してください – Andrie
joran - 私は自分のバージョンのPackageFuncAを保守したくないでしょう。 – SFun28