私は、R の R5 クラス システムで少し遊んで、何ができて何ができないかを確認してきました。そのプロセスで、静的クラス フィールド メンバーのように見えるものに出くわしました (これはドキュメントにはないようですが、見落としていた可能性があります)。
[2014年更新]
警告!!! : 次のコードは R バージョン >= 3.0 では機能しません。
この投稿、その回答、特にコメントは、R5 OO システムと R 言語全般に関する有用な洞察と注意事項を提供します。ただし、R5 クラスのインスタンスの環境を直接使用する慣用句を育てるのはおそらく悪い考えです。
【2014年末更新】
次のコードでは、最初のフィールドはインスタンス フィールド変数の従来の定義です。2 番目の定義は、アクセサー メソッドを使用して静的クラス フィールドを作成するように見えます。この使用法がコーシャかどうか (または私のコード例は単なる偶然かどうか) を知りたいです。3 番目のフィールドの使用では、アクセサー メソッドを使用して準プライベート インスタント フィールド変数を作成します。
assertClass <- function(x, className, R5check=FALSE) {
# simple utility function
stopifnot(class(x)[1] == className)
if(R5check) stopifnot(is(x, 'envRefClass'))
}
A <- setRefClass('A',
fields = list(
# 1. public, typed, instance field
myPublicInstanceVar = 'character',
# 2. this assignment appears static
# but if the field me.static.private
# was declared in the field list
# it would be a local instance var
myPrivateStaticVar = function(x) {
if (!missing(x)) {
assertClass(x, 'character')
me.static.private <<- x
}
me.static.private
},
# 3. quasi-private, typed, instance field
myPrivateInstanceVar = function(x) {
if (!missing(x)) {
assertClass(x, 'character')
.self$me.private <<- x
}
.self$me.private
}
),
methods = list(
initialize = function (c='default') {
myPublicInstanceVar <<- c
myPrivateStaticVar <<- c
myPrivateInstanceVar <<- c
}
)
)
# test instantiation
instance1.of.A <- A$new('first instance')
str(instance1.of.A)
instance2.of.A <- A$new('second instance')
str(instance1.of.A)
str(instance2.of.A)
instance3.of.A <- getRefClass('A')$new('third instance')
instance3.of.A$myPrivateStaticVar <- 'Third instance - changed'
print(instance1.of.A$myPrivateStaticVar)
print(instance2.of.A$myPrivateStaticVar)
print(instance3.of.A$myPrivateStaticVar)
str(instance1.of.A)
str(instance2.of.A)
str(instance3.of.A)
# but not really private ...
instance1.of.A$myPublicInstanceVar # works
instance1.of.A$me.static.private # DOES NOT WORK - where is this variable stored
instance1.of.A$me.private # works
# till death do us part
instance3.of.A <- NULL
gc()
str(instance1.of.A)
str(instance2.of.A)
str(instance3.of.A)
このコードを実行すると、2 番目のフィールド変数が静的クラス メンバーとして動作しているように見えることがわかります。私にはあまり明確ではないのは、参照クラスがこのフィールドを保持する場所です (したがって、上記の最後から 2 番目の行に私のコメントがあります)。