[Rd] unary class union of an S3 class

Hervé Pagès hpages at fredhutch.org
Fri Mar 18 22:53:30 CET 2016


Hi,

Short story
-----------

   setClassUnion("ArrayLike", "array")

   showClass("ArrayLike")  # no slot

   setClass("MyArrayLikeConcreteSubclass",
       contains="ArrayLike",
       representation(stuff="ANY")
   )

   showClass("MyArrayLikeConcreteSubclass") # 2 slots!!

That doesn't seem right.

Long story
----------

S4 provides at least 3 ways to create a little class hierarchy
like this:

        FooLike ............. virtual class with no slot
         ^   ^
         |   |
       foo   anotherfoo ..... 2 concrete subclasses

(1) The "standard" way: define FooLike first, then foo and anotherfoo
as subclasses of FooLike:

   setClass("FooLike")

   setClass("foo",
       contains="FooLike",
       representation(stuff="ANY")
   )

   setClass("anotherfoo",
       contains="FooLike",
       representation(stuff="ANY")
   )

   showClass("FooLike")    # displays foo and anotherfoo as
                           # known subclasses

   x1 <- new("foo")
   is(x1, "foo")           # TRUE
   is(x1, "FooLike")       # TRUE
   is(x1, "anotherfoo")    # FALSE

   x2 <- new("anotherfoo")
   is(x2, "anotherfoo")    # TRUE
   is(x2, "FooLike")       # TRUE
   is(x2, "foo")           # FALSE

Everything works as expected.

(2) Using a class union: define foo and anotherfoo first, then FooLike
as the union of foo and anotherfoo:

   setClass("foo", representation(stuff="ANY"))
   setClass("anotherfoo", representation(stuff="ANY"))
   setClassUnion("FooLike", c("foo", "anotherfoo"))

   showClass("FooLike")    # displays foo and anotherfoo as
                           # known subclasses

(3) Using a *unary* class union: define foo first, then FooLike as the
(unary) union of foo, then anotherfoo as a subclass of FooLike:

   setClass("foo", representation(stuff="ANY"))
   setClassUnion("FooLike", "foo")

   showClass("FooLike")   # displays foo as the only known subclass

   setClass("anotherfoo",
       contains="FooLike",
       representation(stuff="ANY")
   )

   showClass("FooLike")   # now displays foo and anotherfoo as
                          # known subclasses

The 3 ways lead to the same hierarchy. However the 3rd way is
interesting because it allows one to define the FooLike virtual
class as the parent of an existing foo class that s/he doesn't
control.

For example, to define an ArrayLike class:

   setClassUnion("ArrayLike", "array")
   showClass("ArrayLike")  # displays array as a known subclass

Note that ArrayLike is virtual with no slots (analog to a Java
Interface), which is what is expected.

   setClass("MyArrayLikeConcreteSubclass",
       contains="ArrayLike",
       representation(stuff="ANY")
   )

   showClass("MyArrayLikeConcreteSubclass")  # shows 2 slots!!

What is the .Data slot doing here? I would expect to see that slot
if MyArrayLikeConcreteSubclass was extending array but this is not
the case here.

   a <- new("MyArrayLikeConcreteSubclass")

   is(a, "MyArrayLikeConcreteSubclass")  # TRUE  --> ok
   is(a, "ArrayLike")                    # TRUE  --> ok
   is(a, "array")                        # FALSE --> ok

But:

   is.array(a)  # TRUE --> not ok!

Is is.array() confused by the presence of the .Data slot?

I can fix it by defining an "is.array" method for
MyArrayLikeConcreteSubclass objects:

   setMethod("is.array", "MyArrayLikeConcreteSubclass",
       function(x) FALSE
   )

However, it feels that I shouldn't have to do this.

Is the presence of the .Data slot in MyArrayLikeConcreteSubclass
objects an unintended feature?

Thanks,
H.

 > sessionInfo()
R Under development (unstable) (2016-01-07 r69884)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 14.04.4 LTS

locale:
  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8
  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C
  [9] LC_ADDRESS=C               LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

-- 
Hervé Pagès

Program in Computational Biology
Division of Public Health Sciences
Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N, M1-B514
P.O. Box 19024
Seattle, WA 98109-1024

E-mail: hpages at fredhutch.org
Phone:  (206) 667-5791
Fax:    (206) 667-1319



More information about the R-devel mailing list