Class slots vs. initialize signature mismatch

左心房为你撑大大i 提交于 2019-12-08 04:19:57

问题


Consider the following S4 class:

setClass('Foo', representation(model='data.frame'))

setMethod('initialize', 'Foo',
      function(.Object, a, b) {
        .Object@model <- data.frame(a, b)
        .Object
      })

It can be instantiated with:

new('Foo', a=1:4, b=4:7)

So far so good. However, when I try to subclass Foo I get an error.

setClass('Bar', contains='Foo')
>>> Error in data.frame(a, b) : argument "a" is missing, with no default

Personally, I would prefer to instantiate class Foo with explicit arguments because the code is more... well, explicit. However, this does not seem possible, does it? It looks like the signature of initialize must match the slots that the class has, otherwise it's a problem waiting to happen. Am I wrong?


回答1:


The requirement is that new called with no arguments, new("Foo"), must work. Also, it's probably better practice for your initialize method to take ..., to callNextMethod, and to have arguments after the ... (because initialize is documented to use unnamed arguments for initializing contained classes). So

setMethod(initialize, "Foo", function(.Object, ..., a=integer(), b=integer()) {
    callNextMethod(.Object, ..., model=data.frame(a, b))
})

Normally one wants to insulate the user from calling new, and will instead use a constructor Foo. Typically the constructor does whatever coercion you might have instead put in the initialize method, so the initialize method is just not specified.

Foo <- function(a=integer(), b=integer(), ...) {
    model <- data.frame(a, b)
    new("Foo", model=model, ...)
}


来源:https://stackoverflow.com/questions/9957511/class-slots-vs-initialize-signature-mismatch

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