Problems passing arguments with callNextMethod() in R

故事扮演 提交于 2019-12-19 06:19:58

问题


My question:

Why is callNextMethod() not passing arguments as expected to the next method?

Situation:

Say I have two hierarchical classes foo and bar (bar is subclass of foo) for which I have a method foobar that can dispatch for both classes (i.e., has methods for both classes).

Furthermore, the method for the (sub)class bar calls the method for foo after some calculations with callNextMethod().

Both methods have the same additional argument (with default) that should be passed to the method for foo, where only it is relevant.

setClass("foo", representation(x = "numeric"))
setClass("bar", contains = "foo")

setGeneric("foobar", function(object, ...) standardGeneric("foobar"))

setMethod("foobar", "foo", function(object, another.argument = FALSE, ...) {
    print(paste("in foo-method:", another.argument))
    if (another.argument) object@x^3
    else object@x^2
})

setMethod("foobar", "bar", function(object, another.argument = FALSE, ...) {
    print(paste("in bar-method:", another.argument))
     object@x <- sqrt(object@x)
    callNextMethod()
})

Problem description:
The arguments are not passed as expected, but the default values are taken from the method definition. Specifically, in the first method the argument is as specified in the call (TRUE), however, it changes to FALSE in the next method.

o1 <- new("bar", x = 4)

foobar(o1, another.argument = TRUE)

gives

[1] "in bar-method: TRUE"
[1] "in foo-method: FALSE"
[1] 4

I want the another.argument to be passed to the next method so that it is TRUE in the call to the foo method, too.


From ?callNextMethod I get that it should work as expected (i.e., the named argument is passed as it is in the call):

For a formal argument, say x, that appears in the original call, there is a corresponding argument in the next method call equivalent to x = x. In effect, this means that the next method sees the same actual arguments, but arguments are evaluated only once.


My second question: How can I pass another.argument to the next method. (I would really like to keep default arguments in both methods)


回答1:


I think this has to do with the way a method with a signature different from the generic is defined (within a function .local)

> selectMethod(foobar, "bar")
Method Definition:

function (object, ...) 
{
    .local <- function (object, another.argument = FALSE, ...) 
    {
        print(paste("in bar-method:", another.argument))
        object@x <- sqrt(object@x)
        callNextMethod()
    }
    .local(object, ...)
}

Signatures:
        object
target  "bar" 

defined "bar" 

The work-around is to either define the generic and methods to have the same signature

setGeneric("foobar",
    function(object, another.argument=FALSE, ...) standardGeneric("foobar"),
    signature="object")

or pass the arguments explicitly to callNextMethod

setMethod("foobar", "bar", function(object, another.argument = FALSE, ...) {
    print(paste("in bar-method:", another.argument))
     object@x <- sqrt(object@x)
    callNextMethod(object, another.argument, ...)
})


来源:https://stackoverflow.com/questions/7190697/problems-passing-arguments-with-callnextmethod-in-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!