実際の質問
すべてのクラスが ( ではなく) パッケージの名前空間に存在する必要がある場合、継承構造を保持しながら、相互に継承する一連の R6 クラスを S4 クラスに変換するにはどうすればよいGlobalEnv
ですか?
詳細
R6 クラスが で定義されていて.GlobalEnv
( でソーシングする場合source()
など)、setOldClass()
で呼び出されている場合は、すべて正常に機能しwhere = .GlobalEnv
ます。
しかし、パッケージの名前空間内で R6 クラスが定義されている場合 (を呼び出す場合devtools::load_all()
など) 、動作させることができません。
での R6 クラスの定義.GlobalEnv
:
Object <- R6Class("Object", portable = TRUE, public = list(
foo = function() "foo")
)
Api <- R6Class("Api", inherit = Object, portable = TRUE,
public = list(bar = function() "bar")
)
Module <- R6Class("Module", inherit = Api, portable = TRUE,
public = list(fooBar = function() "fooBar")
setOldClass()
で呼び出すwhere = .GlobalEnv
( のデフォルトwhere
):
setOldClass(c("Object", "R6"))
setOldClass(c("Api", "Object"))
setOldClass(c("Module", "Api"))
R6 クラスがパッケージの名前空間内で定義されている場合 (のdevtools::load_all()
代わりに「ソース」を使用する場合などsource()
)、明示的な を提供することでそれを説明する必要があると想定しましたwhere
。
where <- if ("package:r6.s4" %in% search()) {
as.environment("package:r6.s4")
} else {
.GlobalEnv
}
try(setOldClass(c("Object", "R6"), where = where))
try(setOldClass(c("Api", "Object"), where = where))
try(setOldClass(c("Module", "Api"), where = where))
ただし、次のエラーが表示されます。
setOldClass(c("Module", "Api"), where = where) のエラー: 「Module」の古いスタイルのクラス情報に一貫性がありません。クラスは定義されていますが、「Api」を拡張しておらず、データ部分として有効ではありません
再現性の促進
この問題をできるだけ簡単に再現できるように努めたので、私のGitHub リポジトリr6.s4
でパッケージを見つけることができます
エラーを再現するには、実行 (または RStudio でdevtools::load_all()
ヒット)する必要があることに注意してCRTL + SHFT + L
ください。
また、この単体テストは、何が起こっているのかを理解するのに役立つ場合があります。