这是一个扩展在 R 中的访问器函数中使用 callNextMethod() https://stackoverflow.com/q/24875284/2752888.
2017-03-25 更新:为了说明如何仅在加载方法时失败,但在构建的包中时不会失败,我创建了一个虚拟包:https://github.com/zkamvar/inheritest#readme https://github.com/zkamvar/inheritest#readme
基本问题:
我有一个类 bar 继承了另一个类 foo,并且它们都有 [ 方法的附加参数。 foo 的方法始终有效,但 bar 的方法在第一次使用后就会失败。
错误和回溯:
Error in callNextMethod(x, i, j, ..., drop): bad object found as method (class "function")
4: stop(gettextf("bad object found as method (class %s)", dQuote(class(method))),
domain = NA)
3: callNextMethod(x, i, j, ..., drop) at #9
2: .local(x, i, j, ..., drop = drop)
1: BAR["x"]
更多细节:
我有一个包实现了一个类,该类依赖于另一个包中的类。当构建包时,一切正常,但是当我的包被简单加载时(使用devtools::load_all(".")
),我得到下面的行为。
最小工作示例:
foo <- setClass("foo", representation(x = "numeric", y = "numeric"))
bar <- setClass("bar", representation(distance = "numeric"), contains = "foo")
setMethod(f = "[", signature = signature(x = "foo", i = "ANY", j = "ANY", drop = "ANY"),
definition = function(x, i, j, ..., foo = TRUE, drop = FALSE) {
if (foo)
message("FOOOOOOO")
if (i == "x") {
return(x@x)
} else {
if (i == "y") {
return(x@y)
}
}
})
#> [1] "["
setMethod(f = "[", signature = signature(x = "bar", i = "ANY", j = "ANY", drop = "ANY"),
definition = function(x, i, j, ..., bar = TRUE, drop = FALSE) {
if (bar)
message("BAAAAAAR")
if (i == "distance") {
return(x@distance)
} else {
callNextMethod(x, i, j, ..., drop)
}
})
#> [1] "["
FOO <- new("foo", x = 1, y = 4)
BAR <- new("bar", x = 1, y = 4, distance = 3)
FOO["x"]
#> FOOOOOOO
#> [1] 1
BAR["x"]
#> BAAAAAAR
#> FOOOOOOO
#> [1] 1
FOO["x"]
#> FOOOOOOO
#> [1] 1
BAR["distance"]
#> BAAAAAAR
#> [1] 3
BAR["x"] # fails
#> BAAAAAAR
#> Error in callNextMethod(x, i, j, ..., drop): bad object found as method (class "function")
BAR["x", foo = FALSE]
#> BAAAAAAR
#> [1] 1
注意:当我通过这个时reprex https://CRAN.R-project.org/package=reprex,对 BAR 的第一次和最后一次调用也导致了错误,但我正在展示我在交互式会话中所经历的情况。我使用的是 R 版本 3.3.3