2

I'm making right now a R package and I have to chose between returning lists and an object with S3 attributes. The good thing, as for the lists, is that it's very easy to use for beginners, due to the dollar sign making all the elements easy to find. The bad thing, is that it removes direct inheritance (I'd like to return a ts object with some additional informations).

The alternative would be to set the dollar for my S3 class, like this example :

object <- 1
class(object) <- "MyClass"
attr(object,"MyAttribute") <- "This is a secret"

`$.MyClass` <- function(x,name) attr(object,name)

object$MyAttribute

However, I have 2 questions about this :

  • Where to set the dollar partial matching function for the user to see "MyAttribute" as a valid choice in rstudio ?
  • Besides, is that a fine practice to do so or should I keep on using simple lists

Thanks

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
Arnaud Feldmann
  • 761
  • 5
  • 17

1 Answers1

4

I don’t think RStudio currently allows this kind of customisation. In other R terminals you could play with rcompgen to generate completions but IIRC RStudio does its own thing.

That said, your question seems to be based on a false dichotomy:

Besides, is that a fine practice to do so or should I keep on using simple lists

You don’t need to choose either–or. In fact, it’s common to have lists with S3 classes, and it is not common to use attributes to store S3 information that are then accessed via $. Just make your class a list:

object = structure(
    list(value = 1, MyAttribute = "This is a secret"),
    class = "MyClass"
)

object$MyAttribute
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • Thanks. Thats what I did until now. The only bad thing about that is that it don't set direct inheritance for the main contained object, but it is somewhat respectful to the R idiomatics ^^ – Arnaud Feldmann May 05 '20 at 10:52
  • @ArnaudFeld I’m not sure what you mean by that: you can totally “directly” inherit from another S3 class, e.g. `ts`. Simply assign the `class` attribute accordingly. You might however need to override specific methods, since `ts` objects generally have their data as a vector. – Konrad Rudolph May 05 '20 at 10:56
  • I talked about telling to R that one of the elements of the list is the main object of the class. S3 + attributes permits that. You don't have to override methods. S4 permits that with "contains", but I feel like S4 should only be used when it is strictly necessary (otherwise it's a bit overkilling). S3 + lists don't link all inherited methods to the main element. But maybe you can and I don't know something ? – Arnaud Feldmann May 05 '20 at 11:12
  • 1
    @ArnaudFeld I see what you mean now. I don’t think there’s a way without overriding all relevant methods to emulate `contains` with S3. This is what I would do. I also agree with you about avoiding S4. – Konrad Rudolph May 05 '20 at 12:15