オブジェクト全体をメモリにコピーしたり、メソッドの最後に親環境に再書き込みしたりすることなく、S4 オブジェクトのメソッドがそのオブジェクトのスロット内の値を直接調整できるようにする方法はありますか? 現在、独自の状態を追跡するスロットを持つオブジェクトがあります。次の状態に進めるメソッドを呼び出しますが、今のところ、各値 (またはメソッドを呼び出すオブジェクトのコピー) を親環境に assign() する必要があるようです。その結果、オブジェクト指向コードは、ループ内のさまざまな状態変数を単純に調整するコードよりも実行速度が大幅に遅くなるようです。
3 に答える
R には 3 つのオブジェクト指向 (OO) システムがあります: S3、S4および参照クラス(後者はしばらくの間 [[R5]] と呼ばれていましたが、正式名称は参照クラスです)。
参照クラス (または refclasses) は R 2.12 で新しく追加されました。これらは、以前は R.oo、proto、mutatr などのコア以外のパッケージによって満たされていた可変オブジェクトに対する長年のニーズを満たします。コア機能はしっかりしていますが、参照クラスはまだ活発に開発されており、一部の詳細は変更される予定です。参照クラスの最新のドキュメントは、常に ?ReferenceClasses にあります。
参照クラスと S3 および S4 との間には、主な違いが 2 つあります。
- Refclass オブジェクトはメッセージ パッシング OO を使用します
- Refclass オブジェクトは変更可能です。通常の R コピー オン モディファイ セマンティクスは適用されません。
これらのプロパティにより、このオブジェクト システムは Java や C# のように動作します。ここでもっと読む:
私は R リストでこの質問を自分で行い、参照渡しをシミュレートする回避策を見つけました。
eval(
eval(
substitute(
expression(object@slot <<- value)
,env=parent.frame(1) )
)
)
周りの最もクリーンなコードとはかけ離れています...
R ヘルプ リストからの提案では、環境を使用してこれらのケースに対処します。EDIT : 微調整されたコードが挿入されました。
setClass("MyClass", representation(.cache='environment',masterlist="list"))
setMethod("initialize", "MyClass",
function(.Object, .cache=new.env()) {
.Object@masterlist <- list()
callNextMethod(.Object, .cache=.cache)
})
sv <- function(object,name,value) {} #store value
setMethod("sv",signature=c("MyClass","character","vector"),
function(object, name, value) {
object@.cache$masterlist[[name]] <- value
})
rv <- function(object,name) {} #retrieve value
setMethod("rv",signature=c("MyClass","character"),
function(object, name) {
return(object@.cache$masterlist[[name]])
})
私が知る限り (私の理解が正しければ)、オブジェクト全体を再コピーする必要があります。参照によって値を簡単に渡すことはできません。常に「値によって」渡されます。したがって、オブジェクト (のコピー) を変更したら、それをオブジェクトに再コピーする必要があります。
John Chamber は、彼の著書Software for Data Analysisでそれについてかなり明確に述べています。これは、驚きや副作用を避ける方法です。
環境を使用していくつかの回避策があると思いますが、これではどうにもなりません。