Non slot parameters in initialize methods for S4 objects

48 Views Asked by At

I am trying to define an initialize method for an S4 class. According to the documentation of methods::new

Initialize methods are often written when the natural parameters describing the new object are not the names of the slots. If you do define such a method, you should include ... as a formal argument, and your method should pass such arguments along via callNextMethod.

and the documentation of methods::initialize-methods

For example, suppose you want to define a method for your class, with special argument x, but you also want users to be able to set slots specifically. If you want x to override the slot information, the beginning of your method definition might look something like this:

function(.Object, x, ...) {
  Object \<- callNextMethod(.Object, ...)
  if(!missing(x)) { # do something with x

Of course, my use case is a bit more complex. The slot is an S3 object which is set to an S4 by setOldClass. What I want is to initialize the S3 object in the slot with just a string provided by the user and thus hide from the user the internal implementation of myClass. At the same time, I want to keep the possibility for an advanced user to initialize the internal object and provide it to the new method if needed.


A basic example of what I am trying to achieve:

setClass(
  Class = "myClass",
  slots = c(
    myString = "character"
  )
)

setMethod(
  "initialize",
  signature = "myClass",
  definition = function(.Object, string = "Hello", ...) {
    .Object <- callNextMethod(.Object, ...)

    .Object@myString <- paste0("My string is ", string)

    validObject(.Object)

    .Object
  }
)

However if I do that, I always receive error stating that string is not a slot of class myClass.

r$> new("myClass", string = "my string")
Error in initialize(value, ...) : 
  invalid name for slot of class “myClass”: string 

Of course I can do an explicit contructor for myClass, wrap the logic in it and pass the final string to the slot (which might be the better practice and it is what I am doing at the moment):

myClass <- function(string) {
  new("myClass", myString = paste0("My string is ", string))
}

but I do not understand why it is not working with the initialize method.

0

There are 0 best solutions below