Skip to content
Prev 9608 / 21312 Next

[Bioc-devel] S4 overwrite inspector of virtual class

Ah, yeah we usually call them validator functions or (more commonly)
validity functions/validity method.

The issue with what you want is that if A is a superclass of B (B inherits
from  or "contains" A) then objects of class B must be valid objects of
class A. From ?validObject (emphasis mine)

 Validity testing takes place 'bottom up': Optionally, if
     'complete=TRUE', the validity of the object's slots, if any, is
     tested.  Then, *in all cases, for each of the classes that this*
*     class extends (the 'superclasses'), the explicit validity method*
*     of that class is called, if one exists.*  Finally, the validity
     method of 'object''s class is called, if there is one.

So the system is specifically designed not to allow what you're asking, as
it violates one of the tenets of R's version of OOP. The virtual class
should contain only slots, validity checks, etc that apply to literally all
subclasses.

There are ways to get around this, such as if a slot indicates what version
it is in your chromosome example, the validity check in the virtual class
could behave differently based on the value of that slot. This blurs the
line between differentiating behavior on objects by class or by contents,
though, so should (I think) be used sparingly and with care. Generally you
want to use method dispatch for class-specific differences in behavior.

Basically if a check should be different for different subclasses, it
shouldn't go in the validity method for the virtual, it should be explicit
in the the validity methods for each subclass. Keep in mind you can assign
an existing R closure (function) there, so you don't have to repeat code,
just do

.lcaseCheck = function(object) {blabla}
.ucaseCheck = function(object) {BlaBla}


and use .lcaseCheck and .ucaseCheck either as the validity functions for
your classes if they that is the only check:

setClass("CoolThing", ..., validity=.lcaseCheck)
setClass("EvenCoolerThing", ..., validity = .lcaseCheck)
setClass("DifferentCoolThing", ..., validity = .ucaseCheck)


or within them as necessary. You can dispatch on the class within a
validity method from what I can see, but that is probably overkill for a
case like this.


HTH,
~G
On Mon, Aug 15, 2016 at 9:56 AM, Zach Skidmore <zskidmor at wustl.edu> wrote: