Jens Oehlschlägel
2009-Dec-28 14:31 UTC
[R] Ops method does not dispatch on either of two classes
I have defined boolean methods for bit and bitwhich objects, for example |.bit <- function(e1,e2) and |.bitwhich <- function(e1,e2) Both methods coerce their arguments to the respective class, however if I do something like bit_obj | bitwhich_obj then I get a warning Warning message: Incompatible methods ("|.bit", "|.bitwhich") for "|" and none of the two methods is called. Instead the (internal) method for logicals seems to be called - not even coercing its arguments to logical. Same problem with Ops.bit and Ops.bitwhich . What is the recommended way to get my methods reliably dispatched? Jens Oehlschl?gel
Prof Brian Ripley
2009-Dec-30 09:21 UTC
[R] Ops method does not dispatch on either of two classes
This is as documented on the help page for Ops (the page in base, not the one in Methods) which is linked from ?"|". For background you should also read the reference on that help page. You are wrong in asserting that the internal method is 'for logicals': please do study the help page. It covers e.g. integer vectors which is what I suspect you have here (assuming this is something to do with package 'bit', unmentioned). On Mon, 28 Dec 2009, Jens Oehlschl?gel wrote:> I have defined boolean methods for bit and bitwhich objects, for example > |.bit <- function(e1,e2) > and > |.bitwhich <- function(e1,e2) > > Both methods coerce their arguments to the respective class, however > if I do something like > > bit_obj | bitwhich_obj > > then I get a warning > > Warning message: > Incompatible methods ("|.bit", "|.bitwhich") for "|" > > and none of the two methods is called. Instead the (internal) method > for logicals seems to be called - not even coercing its arguments to > logical. Same problem with Ops.bit and Ops.bitwhich . > > What is the recommended way to get my methods reliably dispatched?They are! Take a look at what classes in R itself have S3 Ops methods and how they achieve what you seem to want via class inheritance.> Jens Oehlschl?gel > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >-- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
Jens Oehlschlägel
2009-Dec-31 14:12 UTC
[R] Ops method does not dispatch on either of two classes
Thanks Brian,> This is as documented on the help page for Ops (the page in base, not > the one in Methods) which is linked from ?"|". For background you > should also read the reference on that help page.Unfortunately I have no access to that book.> You are wrong in asserting that the internal method is 'for logicals': > please do study the help page. It covers e.g. integer vectors which > is what I suspect you have here (assuming this is something to do with > package 'bit', unmentioned).Yes, both "bit" and "bitwhich" are integer with an S3 class attribute (bitwhich sometimes is logical instead). I am lost. What do I need to do to get "|.a" dispatched if calling a | b where "a" and "b" are objects from S3 classes "a" and "b" that both have methods defined for "|" ? In the R Language definition I find "If they do not suggest a single method then the default method is used." Does this mean it is not possible to write Ops methods for classes "a" and "b" such that "|.a" is called in a | b ? I don't see how I can get any hook into the dispatch mechanism, my methods are always bypassed if the classes of e1 and e2 differ (simple example below). Best wishes for 2010 Jens Oehlschl?gel> ca <- function(x){+ x <- as.integer(x) + oldClass(x) <- "a" + x + }> cb <- function(x){+ x <- as.integer(x) + oldClass(x) <- "b" + x + }> > a <- ca(1) > b <- cb(1) > > Ops.a <-+ function(e1, e2){ + cat("here Ops.a \n") + NULL + }> > Ops.b <-+ function(e1, e2){ + cat("here Ops.a \n") + NULL + }> > # OK, "Ops.a" dispatched > a | ahere |.a NULL> > # BUT both, "Ops.a" and "Ops.b" bypassed > a | b[1] TRUE Warning message: Incompatible methods ("|.a", "|.b") for "|"> > > "|.a" <- function(e1, e2){+ cat("here |.a \n") + NULL + }> > "|.b" <- function(e1, e2){+ cat("here |.b \n") + NULL + }> > # OK, "|.a" dispatched > a | ahere |.a NULL> > # BUT both, "|.a" and "|.b" bypassed > a | b[1] TRUE Warning message: Incompatible methods ("|.a", "|.b") for "|"