私はS4リファレンスクラスの大ファンです。ハイブリッドプログラミングスタイル(機能/値渡しとoop /リファレンス渡し;例)が可能であり、柔軟性が劇的に向上します。
ただし、メソッドを介して特定のフィールド値を取得するように要求したときに、Rが環境/フレームをスキャンする方法に関して望ましくない動作に遭遇したと思います$field()
(ヘルプページを参照)。問題は、実際のローカル/ターゲット環境(S4参照クラスを構成する環境)で目的のフィールドが見つからない場合、つまり実行中のように、Rが環境/フレームを囲んでいるように見えることです(ヘルプをget(<objname>, inherits=TRUE)
参照)ページ)。
実際の質問
Rにローカル/ターゲット環境だけを見てもらうために、私は次のようなことを考えていましたが、私が渡すことを可能にする引数$field(name="<fieldname>", inherits=FALSE)
が$field()
ありません(これは途中で呼ばれていると思います)。これに対する回避策はありますか?...
inherits=FALSE
get()
コード例
詳細に興味のある方へ:動作を説明する小さなコード例を次に示します。
setRefClass("A", fields=list(a="character"))
x <- getRefClass("A")$new(a="a")
a
クラスにフィールドがあるA
ため、ターゲット環境で検出され、値が返されます。
> x$field("a")
[1] "a"
参照クラスのフィールドではないが、ワークスペース/検索パス(この場合"lm"
)の他のオブジェクトの名前と同じ名前のフィールドにアクセスしようとすると、状況が異なります。
require("MASS")
> x$field("lm")
function (formula, data, subset, weights, na.action, method = "qr",
model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE,
contrasts = NULL, offset, ...)
{
ret.x <- x
ret.y <- y
[omitted]
if (!qr)
z$qr <- NULL
z
}
<bytecode: 0x02e6b654>
<environment: namespace:stats>
現時点で私が期待することではありません。私見エラーまたは少なくとも警告ははるかに良いでしょう。$field()
または、を介して他の関数に渡すことができる引数のメソッドを開き...
ます。get()
を呼び出すときに途中で呼び出されると推測している$field()
ので、次のようなものが上記の動作の発生を防ぐ可能性があります。
x$field("digest", inherits=FALSE)
回避策:独自の提案
これでうまくいくはずですが、次のような新しいメソッドの指定を伴わない、よりエレガントなものがあるかもしれません$field()
。
setRefClass("A", fields=list(a="character"),
methods=list(
myField=function(name, ...) {
# VALIDATE NAME //
if (!name %in% names(getRefClass(class(.self))$fields())) {
stop(paste0("Invalid field name: '", name, "'"))
}
# //
.self$field(name=name)
}
)
)
x <- getRefClass("A")$new(a="a")
> x$myField("a")
[1] "a"
> x$myField("lm")
Error in x$myField("lm") : Invalid field name: 'lm'