Проблемы с передачей аргументов с помощью callNextMethod () в R - PullRequest
7 голосов
/ 25 августа 2011

Мой вопрос:

Почему callNextMethod() не передает аргументы, как ожидалось, следующему методу?

Положение:

Скажем, у меня есть два иерархических класса foo и bar (bar является подклассом foo), для которых у меня есть метод foobar, который может отправлять для обоих классов (т. Е. Имеет методы для обоих классов ).

Кроме того, метод для (под) класса bar вызывает метод для foo после некоторых вычислений с callNextMethod().

Оба метода имеют один и тот же дополнительный аргумент (по умолчанию), который должен быть передан методу для foo, где только он уместен.

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()
})

Описание проблемы:
Аргументы не передаются должным образом, но значения по умолчанию берутся из определения метода. В частности, в первом методе аргумент соответствует значению, указанному в вызове (TRUE), однако в следующем методе он изменяется на FALSE.

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

foobar(o1, another.argument = TRUE)

дает

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

Я хочу, чтобы another.argument был передан следующему методу, чтобы при вызове метода foo он был TRUE.


С ?callNextMethod Я получаю, что он должен работать как положено (то есть, именованный аргумент передается так же, как в вызове):

Для формального аргумента, скажем, х, который появляется в исходном вызове, есть соответствующий аргумент в следующем вызове метода, эквивалентный x = Икс. По сути, это означает, что следующий метод видит тот же фактический аргументы, но аргументы оцениваются только один раз.


Мой второй вопрос : Как я могу передать другой аргумент следующему методу. (Мне бы очень хотелось сохранить аргументы по умолчанию в обоих методах)

1 Ответ

4 голосов
/ 25 августа 2011

Я думаю, что это связано с тем, как определяется метод с сигнатурой, отличной от универсального (в функции .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" 

Обходной путь - определить универсальный иметоды с одинаковой подписью

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

или явной передачей аргументов 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, ...)
})
...