实际问题
当所有类都需要位于包的命名空间中(而不是 in )时,如何将一堆相互继承的 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
中找到该包
再次注意,您必须运行devtools::load_all()
(或CRTL + SHFT + L
在 RStudio 中点击)才能重现错误。
此外,这个单元测试可能有助于弄清楚发生了什么。