Hi John, John Chambers wrote: > The "infelicity" arises because validObject() is not a generic function; > validity "method" is a bit of a misnomer.
Indeed. And I guess referring to "method dispatch" like I did in my previous email is not appropriate either. So yes I learned that thinking of validity "methods" as regular methods doesn't really work. For example the man page for callNextMethod is stating that "a call to 'callNextMethod' can only appear inside a method definition" but it won't work inside a validity "method". Why would I need to do that? Well the problem I reported in this thread can be worked around by redefining the the same validity method for "PosInts2" objects as for "PosInts" objects. So while I was looking at different ways to achieve this, I tried this (I really want to avoid code duplication): setValidity("PosInts2", function(object) callNextMethod()) which of course doesn't work, so I finally came up with something like this: setValidity("PosInts2", getValidity(getClassDef(extends("PosInt2")[2]))) which tries to mimic what callNextMethod would do but in an ugly and easy to break way. This is a temporary fix anyway, until validObject(..., complete=TRUE) is fixed in R 2.8.0. > The functions are attached to > the class definition and validObject looks for them directly--in the > process it catches all methods from superclasses, but not from > superclasses of the slots' classes. > > The fix is to call validObject recursively on each slot when > complete=TRUE. This is a moderately large efficiency hit, but if you're > using complete=TRUE, it's reasonable to assume you really want the whole > truth, even if it takes a bit longer. Absolutely. Thanks for looking into this! Cheers, H. > > Unless there are counter-arguments, we'll make this change (not, > however, for 2.7.0) > > John > > Herve Pages wrote: >> Hi, >> >> When called with complete=TRUE, validObject() is supposed to work in a >> recursive manner. But here is a situation where it doesn't seem to be >> the case. >> >> Let's define a class with a validity method: >> >> setClass("PosInts", representation(ii="integer")) >> >> setValidity("PosInts", >> function(object) >> { >> if (!all([EMAIL PROTECTED] > 0)) >> return("'ii' slot contains non-positive values") >> NULL >> } >> ) >> >> Let's extend this class (no need to add new slots for illustrating the >> pb): >> >> setClass("PosInts2", contains="PosInts") >> >> broken <- new("PosInts2") >> [EMAIL PROTECTED] <- 3:0 >> >> If "PosInts2" objects don't need to satisfy additional constraints in >> order to >> be considered valid, then I don't need to define a validity method for >> them. >> I can just rely on method dispatch, which works as expected with >> validity methods: >> >> > validObject(broken) >> Error in validObject(broken) : >> invalid class "PosInts" object: 'ii' slot contains non-positive >> values >> >> Unfortunately, this will cause problems later when I try to validate >> objects >> that have slots of type "PosInts2": >> >> setClass("A", representation(aa="PosInts2")) >> a <- new("A", aa=broken) >> >> This works as expected: >> >> > validObject(a) >> [1] TRUE >> >> But this is not what I would expect: >> >> > validObject(a, complete=TRUE) >> [1] TRUE >> >> ... given that 'a' has a slot that contains an invalid "PosInts2" >> instance: >> >> > validObject([EMAIL PROTECTED]) >> Error in validObject([EMAIL PROTECTED]) : >> invalid class "PosInts2" object: 'ii' slot contains non-positive >> values >> >> So clearly 'a' is broken and I would expect validObject(a, >> complete=TRUE) to >> tell me so... >> >> Now if I define the same validity method for "PosInts2" objects as for >> "PosInts" >> objects, then things work as expected (validObject(a, complete=TRUE) >> will fail) >> but it's not clear to me why I should be forced to do this? >> >> Thanks! >> >> H. >> >> ______________________________________________ >> R-devel@r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel >> >> > ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel