7

私の質問:

callNextMethod()次のメソッドに期待どおりに引数を渡さないのはなぜですか?

状況:

2つの階層クラスがfooあり、barbarのサブクラスはfoofoobar両方のクラスにディスパッチできるメソッドがある(つまり、両方のクラスのメソッドがある)とします。

さらに、(サブ)クラスのメソッドは、を使用していくつかの計算を行った後bar、のメソッドを呼び出します。foocallNextMethod()

どちらのメソッドにも同じ追加の引数(デフォルト)があり、これはのメソッドに渡される必要が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次のメソッドに渡して、メソッドTRUEの呼び出しにも含まれるようにしますfoo


期待どおり?callNextMethodに機能するはずです(つまり、名前付き引数は呼び出しの場合と同じように渡されます)。

元の呼び出しに表示される仮引数、たとえばxの場合、次のメソッド呼び出しにはx=xに相当する対応する引数があります。実際、これは、次のメソッドが同じ実際の引数を参照するが、引数は1回だけ評価されることを意味します。


2番目の質問:another.argumentを次のメソッドに渡すにはどうすればよいですか。(私は本当に両方のメソッドでデフォルトの引数を保持したいと思います)

4

1 に答える 1

4

これは、ジェネリックとは異なるシグネチャを持つメソッドが(関数.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, ...)
})
于 2011-08-25T15:43:48.630 に答える