質問
RIで新しい参照クラスを試している間、x $ dosomethingの代わりに、「[[["dosomething"]]の「[[[]]」」表記を使用すると、奇妙な動作に気づきました。この表記法はフィールドで機能しますが、最初は「クラス(x $ dosomething)」を実行すると「[[]]」を使用できることがわかったまで、方法では機能しないと考えました。以下の簡単な例は、ポイントを示しています。
setRefClass("Number",
fields = list(
value = "numeric"
),
methods = list(
addOne = function() {
value <<- value + 1
}
)
)
X <- new("Number", value = 1)
X[['value']] # 1
X[["addOne"]]() # Error: attempt to apply non-function
class(X[["addOne"]]) # NULL
class(X$addOne) # "refMethodDef"
# Now the following works!
X[["addOne"]]() # sets X$value = 2
class(X[["addOne"]]) # "refMethodDef"
これに遭遇した理由は、オブジェクトをリストにグループ化し、各オブジェクトに指定されたメソッドを適用する「ApplyMethod」関数を作成したいからです。したがって、メソッドを文字列として指定する必要があります。誰かが私がこれを達成できる方法を持っていますか?
解決
これがクラスです
.A <-
setRefClass("A",
fields=list(x="numeric"),
methods=list(foo=function() x))
インスタンスがあった場合 a
そして、「$」を使用して「foo」メソッドへの電話を作成したかった
eval(substitute(a$FUN(), list(FUN="foo")))
だからクラスを作成します Alist
それはクラスの要素のリストを持つことを意図しています A
(これはプログラムで強制される可能性があります)、そしてそれは .delegate
リストのすべての要素に任意の方法を適用する方法。次に、委任する方法を追加します foo
.
.delegate <- function(FUN, ...)
{
lapply(elts, function(elt, ...) {
eval(substitute(elt$FUN(...), list(FUN=FUN, ...)))
})
}
.Alist <-
setRefClass("Alist",
fields=list(elts="list"),
methods=list(
initialize = function(...) callSuper(elts=list(...)),
.delegate = .delegate,
foo=function() .delegate("foo")))
そしてそれを使用します
> aList <- .Alist$new(.A$new(x=1), .A$new(x=2))
> aList$foo()
[[1]]
[1] 1
[[2]]
[1] 2
他のヒント
基本的にR5 REFクラスは、必要になるまでメソッドをキャッシュしません。これはおそらく一種の遅延評価です。
そして、あなたがメソッドにアクセスするときにキャッシュが行われます $
。だから、Afaik、[[String]]を介してメソッドにアクセスする方法はありません
ただし、このような.dollarforenvrefclassを使用して回避策を見つけることができます。
> X <- new("Number", value = 1)
> ls(X@.xData)
[1] "value" # no methods named "addOne" before caching
> X[["addOne"]]
NULL
> methods:::.dollarForEnvRefClass(X, "addOne") # cache it
Class method definition for method addOne()
function ()
{
value <<- value + 1
}
<environment: 0x116a4aa00>
> ls(X@.xData)
[1] "addOne" "value" # you can find it
> X$value # value is 1
[1] 1
> X[["addOne"]]() # call the method
> X$value # the method works
[1] 2
より詳細に興味がある場合は、実装を参照してください。
http://svn.r-project.org/r/trunk/src/library/methods/r/refclass.r
たぶんもっと簡単な方法があります。
R-Develのバグとして報告して、John Chambersがそれを修正できるようにします。