[Rd] Class union of custom classes

Ezra Tucker ezr@ @end|ng |rom |@ndtucker@com
Sun Jul 3 19:56:34 CEST 2022


Hi Pantelis,

What usually helps me in these kinds of puzzles is splitting out
(mentally) the s4 part from the s3 part. The first test you mention,
using the class "withId" has an s3 part of a "maybeNumber" (numeric or
logical) and an s4 part of a slot "id". Kind of hidden will be a second
slot, ".Data" which contains the s3 data --The w1 value you get is
essentially a numeric, and will be subject to numeric methods (ie you
could do w1 + 2) and it'll add 2 to all of the values in the .Data
slot.

Test 2:
part of the reason setClassUnion works in Test 1 is because the member
classes of withID have the same slots-- both of them are .Data.
However, the definition of "foo" in this test has one slot, xb, which
is logical, and no .Data slot/no s3 part. foo and withId have
incompatable initializers (the "initialize" method for their respective
classes so that's why you're seeing this error.

Test 3:
In general, I'd probably avoid using setIs, as it sets an explicit
relationship between two classes, whether or not it's logical to do so.
While the initializer for "maybeNumber" ought to complete, because of
the issues raised above about Test 2, it'll prevent the object from
being created.

Test 4:
This one's tricky. A revealing question is, what happens when you try

> w1 <- new("withId", TRUE, id = "test 4")

Error in initialize(value, ...) : 
  cannot use object of class "logical" in new():  class "withId" does
not extend that class

wheras if you did

> setClass("withId", slots = c(data = "maybeNumber", id = "character"))
> w1 <- new("withId", data = new("foo", TRUE), id = "test 4")

it should work properly (or you could do data = 1.2 - it won't
recognize a value TRUE as being of class foo since it's logical. Your
withId has to have .Data of class numeric or foo, which themselves have
incompatible initializers.

Hopefully this helps!

-Ezra

On Sun, 2022-07-03 at 13:02 +0200, pikappa.devel using gmail.com wrote:
> Dear all,
> 
>  
> 
> This code, mostly copied from the setClassUnion help page, works as
> described in the documentation:
> 
>  
> 
> # test 1
> 
> setClassUnion("maybeNumber", c("numeric", "logical"))
> 
> setClass("withId", contains = "maybeNumber", slots = c(id =
> "character"))
> 
> w1 <- new("withId", 1.2, id = "test 1")
> 
>  
> 
> However, the following three tests do not work:
> 
>  
> 
> # test 2
> 
> setClass("foo", slots = list(xb = "logical"))
> 
> setClassUnion("maybeNumber", c("numeric", "foo"))
> 
> setClass("withId", contains = "maybeNumber", slots = c(id =
> "character"))
> 
> w1 <- new("withId", 1.2, id = "test 2")
> 
>  
> 
> # test 3
> 
> setClass("foo", slots = list(xb = "logical"))
> 
> setClassUnion("maybeNumber", c("numeric"))
> 
> setIs("foo", "maybeNumber")
> 
> setClass("withId", contains = "maybeNumber", slots = c(id =
> "character"))
> 
> w1 <- new("withId", 1.2, id = "test 3")
> 
>  
> 
> # test 4
> 
> setClass("foo", contains = "logical")
> 
> setClassUnion("maybeNumber", c("numeric", "foo"))
> 
> setClass("withId", contains = "maybeNumber", slots = c(id =
> "character"))
> 
> w1 <- new("withId", 1.2, id = "test 4")
> 
>  
> 
> All three return:
> 
>  
> 
>   Error in initialize(value, ...) : 
> 
>       'initialize' method returned an object of class "numeric"
> instead of
> the required class "withId"
> 
>  
> 
> The error comes from:
> 
>  
> 
> traceback()
> 
> 3: stop(gettextf("'initialize' method returned an object of class %s
> instead
> of the required class %s", 
> 
>        paste(dQuote(class(value)), collapse = ", "),
> dQuote(class(.Object))), 
> 
>        domain = NA)
> 
> 2: initialize(value, ...)
> 
> 1: new("withId", 1.2, id = "test 2")
> 
>  
> 
> I would expect tests 2-4 to work similarly to the first test. Is the
> above
> error the intended behavior of setClassUnion? I do not see anything
> that
> would prevent this in the documentation. Is there something I am
> missing
> here?
> 
>  
> 
> Any help would be very much appreciated!
> 
>  
> 
> Kind regards,
> 
> Pantelis
> 
> 
>         [[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