[Rd] Unexpected behavior with inheritance and using S3 classes as slots in S4 class

Simon Urbanek @|mon@urb@nek @end|ng |rom R-project@org
Thu Jan 28 09:41:12 CET 2021


Ezra,

I think it's just the fact the you specified the wrong class inheritance in setOldClass() - it has to match you S3 definition, so it should be:

setOldClass(c("b","a"))

In which case it works:

> n(s1 = b_1)
An object of class "n"
Slot "s1":
[1] "world"
attr(,"class")
[1] "b" "a"

Cheers,
Simon



> On Jan 28, 2021, at 15:55, Ezra Tucker <ezra using landtucker.com> wrote:
> 
> Hi all,
> 
> I have a situation where I'm trying to use S3 classes as slots in an S4 class and am running into some problems with inheritance.
> 
> My example:
> ## with S3 classes
> a <- function(x) structure(x, class = "a")
> b <- function(x) structure(x, class = c("b", "a"))
> setOldClass(c("a", "b"))
> 
> a_1 <- a("hello")
> b_1 <- b("world")
> n <- setClass("n", slots = c(s1 = "a"))
> n(s1 = a_1) # works as expected
> is(b_1, "a") # yields TRUE
> n(s1 = b_1) # doesn't work-- unexpected
> 
> Error message is:
> Error in validObject(.Object) :
> invalid class “n” object: invalid object for slot "s1" in class "n": got class "b", should be or extend class "a"
> 
> Digging in, validObject looks like it's calling getClassDef, which gives me
>> getClassDef("b")
> Virtual Class "b" [in ".GlobalEnv"]
> 
> Slots:
> 
> Name: .S3Class
> Class: character
> 
> Extends: "oldClass"
> 
> -- it extends "oldClass" but it doesn't extend class "a" despite the fact the S3 version does.
> 
> Now, In this simple example, I could have defined a and b as s4 classes, but in the real world, I didn't define them and have to use setOldClass.
> I'm currently getting around this issue by doing setClassUnion("ab", c("a", "b")) and then specify to use "ab" as the type for the slot, but since I already know b inherits from a, this ought not to be necessary (and there are other reasons this is undesirable).
> 
> 1. Is there anything I missed, in setting up this simple example, that would cause n(s1 = b_1) to work properly? Or is there anything I should do other than setClassUnion?
> 2. Is this a shortcoming of validObject or getClassDef?
> 
> Thank you all!
> -Ezra
> 	[[alternative HTML version deleted]]
> 
> ______________________________________________
> R-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



More information about the R-devel mailing list