使用带有dotsMethods的`callNextMethod()`

时间:2017-04-19 14:52:10

标签: r oop generics s4

我想在...参数上定义一些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代码中无法完全复制)。然而,不同计算的情况到目前为止还没有遇到过结果,而且似乎不太可能。

0 个答案:

没有答案