我想在...
参数上定义一些S4泛型调度,以便更专业的方法通过callNextMethod()
调用继承的方法。但是,如MWE所示,这会因以下错误而失败。
# sample function which returns the number of its arguments
f <- function(...) length(list(...))
setGeneric("f")
## [1] "f"
setMethod("f", "character", function(...){ print("character"); callNextMethod() })
## [1] "f"
f(1, 2, 3)
## [1] 3
f("a", "b", "c")
## [1] "character"
## Error in callNextMethod(): a call to callNextMethod() appears in a call to '.Method', but the call does not seem to come from either a generic function or another 'callNextMethod'
这种行为对我来说似乎不对,但也许我在这里遗漏了一些东西。我希望失败的callNextMethod()
能够有效地返回到继承的默认方法function(...) length(list(...))
:
## [1] "character"
## [1] 3
对此有何想法?
此外,我发现S4方法调度正式参数和调度...
之间的行为有以下差异。请考虑以下示例,其中将签名从x
切换为...
会更改对象的解析方式。
f = function(x, ..., a = b) {
b = "missing 'a'"
cat(a)
}
f()
## missing 'a'
f(a = 1)
## 1
setGeneric("f", signature = "x")
f()
## missing 'a'
setGeneric("f", signature = "...")
f()
## Error in cat(a) : object 'b' not found
根据?dotsMethods
,...
上的发送方式有所不同,但正如最后一句所述,与常规泛型相比,这不应导致行为上的任何差异。但是,上述发现似乎正好相反。
在R的2.8.0版本中引入了调用“...”的方法。相应的选择和调度的初始实现是在R函数中,为了灵活性而正在研究新机制。在该实现中,在通用功能的环境中插入本地版本的setGeneric。本地版本根据上述标准选择一种方法,并从通用函数的环境中调用该方法。这与C实现在不涉及“...”时采取的行动略有不同。除了所需的额外计算时间之外,该方法在真正的函数调用中进行评估,而不是由C版本构建的特殊上下文(在R代码中无法完全复制)。然而,不同计算的情况到目前为止还没有遇到过结果,而且似乎不太可能。