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

Ezra Tucker ezr@ @end|ng |rom |@ndtucker@com
Thu Jan 28 15:36:12 CET 2021


Wow - can't believe it was that simple (and obvious now that I see the answer). Thanks Simon!

-Ezra

--
ezra using landtucker.com
m: 818-203-0269
LinkedIn: linkedin.com/in/ezztucker
Github: github.com/minimenchmuncher

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐

On Thursday, January 28th, 2021 at 8:41 AM, Simon Urbanek <simon.urbanek using R-project.org> wrote:

> 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