setClassUnion()---at least in my case---solves the problem;
The problem arises if I have a direct superclass "competing"
with the new class generated by setClassUnion();
consider the following code:
## C00 mother class to C01 and C02
setClass("C00", representation(a="numeric"), prototype =c(a=0))
setClass("C01", representation(a="numeric",b="numeric"), contains= "C00")
setClass("C02", representation(a="numeric",d="numeric"), contains= "C00")
#with setClassUnion:
setClassUnion("C01OrC02", c("C01","C02"))
# "+" methods for C00 and C01OrC02
# that this is a function to be dispatched on two arguments is
# not important for this example
setMethod("+", signature=c("C00","C00"), function(e1,e2){e1 at a+e2@a})
setMethod("+", signature=c("C01OrC02","C01OrC02"),
function(e1,e2){if(is(e1,"C01")) e10 <- e1
# else: explicit coercion from C02 to C01
else e10 <- new("C01", a=e1 at a, b=e1 at d)
if(is(e2,"C01")) e20 <- e2
# else: explicit coercion from C02 to C01
else e20 <- new("C01", a=e2 at a, b=e2 at d)
e10 at b+e20@b})
x1=new("C02", a=1, d=2)
x2=new("C02", a=1, d=3)
x1+x2 ## 2, i.e. uses C00-method
# but I would like to force usage of C01OrC02-method
Here the two classes C00 and C01OrC02 are direct superclasses to
C02, which exactly reflects my application of distribution classes,
confer https://stat.ethz.ch/pipermail/r-devel/2006-April/037190.html
How does the dispatching mechanism decide between
these two and is there a way to change precedence?
Of course, I could implement a "+" method for C02 directly
in this case, but suppose I have much more methods for
C01 and I want to use /all/ of them for C02, and cannot
organize things so that we have the inheritance chain
C00 -> C01 -> C02. What is the preferred way of doing
this?
Thank you already for your attention,
Peter
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Dear John,
sorry for having bothered you with these problems.
As I think Seth told you before, if you want to control the order
of inheritance at the same level, you need to use the intended order
in the contains= argument to setClass.
Apologies, but I did not catch this from Seth's mail; in fact Seth wrote
With the contains arg, the order determines the precedence for method
lookup.
sorry for coming up again with the same question.
In your example (retaining the class union, although it's not required,
the superclass
could just be an ordinary virtual class),
setClassUnion("C01OrC02")
## C00 mother class to C01 and C02
setClass("C00", representation(a="numeric"), prototype =c(a=0))
setClass("C01", representation(a="numeric",b="numeric"),
contains= c("C01OrC02", "C00"))
setClass("C02", representation(a="numeric",d="numeric"),
contains= c("C01OrC02", "C00"))
seems to give what you want
Yes, it does. Thank you very much. Problem solved!
... and I have learned something ....
Besides the importance of order in the 'contains'-arg,
beforehand, I had also somehow misunderstood the
purpose of setClassUnion():
I had thought setClassUnion() was to circumvene the
modification of classes (not "owned" by me);
thus it was not obvious to me to write a class defined
by setClassUnion() into the 'contains'-argument.
BTW:
Is there a way to solve my problem without
modifying the 'contains'-arguments ---
e.g. if I do not "own" classes C01, C00, C02?
(This is not the case for my application, but
might be of general interest) .
To answer one of your other questions, the point about inheritance
asserting
substitutability is that you now need to be sure that
EVERY method for C01OrC02 is preferred to a method for C00 for
the new subclasses.
Ok. This would be the case in my application.
As a general design point, having these competing superclasses is likely to
confuse the user, if not the implementer.
If you could, it would make a clearer picture to have, e.g., C01orC02 be a
subclass of C00.
Then the inheritance is obvious--C01or... is a parent, while C00 is a
grandparent.
The special contains= then doesn't need to be repeated for every
subclass Cx.
Good point; I fixed this in our package.
Probably it is also a good idea then not to export this artificial
(but no longer VIRTUAL) intermediate class in the NAMESPACE file.
Thank you once again, you helped us a lot.
Peter
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (MingW32)
Comment: GnuPT 2.6.2.1 by EQUIPMENTE.DE
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFEPbFex+/gN8KI3u0RAgE8AJ9/M6Q7F8ldGDLVjRCCXW6PdidJRwCfW2zd
rFlFbzuL4jbrav//lmrO2rE=
=iIbA
-----END PGP SIGNATURE-----