r - S3 operator overloading for multiple classes -
i defined 2 classes can add 2 of own objects or number , 1 of own objects.
a <- structure(list(val = 1), class = 'customclass1') b <- structure(list(val = 1), class = 'customclass2') `+.customclass1` <- function(e1, e2, ...){ val1 <- ifelse(is.numeric(e1), e1, e1$val) val2 <- ifelse(is.numeric(e2), e2, e2$val) val_res <- val1 + val2 print('customclass1') return(structure(list(val = val_res), class = 'customclass1')) } `+.customclass2` <- function(e1, e2, ...){ val1 <- ifelse(is.numeric(e1), e1, e1$val) val2 <- ifelse(is.numeric(e2), e2, e2$val) val_res <- val1 + val2 print('customclass2') return(structure(list(val = val_res), class = 'customclass1')) } print.customclass1 <- function(x, ...){ print(x$val) } print.customclass2 <- function(x, ...){ print(x$val) } + # [1] 2 + 1 # [1] 2 b + b # [1] 2 1 + b # [1] 2
but obviously, goes wrong when try add 2 custom classes.
a + b # error in + b : non-numeric argument binary operator # in addition: warning message: # incompatible methods ("+.customclass1", "+.customclass2") "+"
i define 1 function customclass1, function not work when try add 2 customclass2 objects. there way prioritize 1 function on other?
r seems naturally prioritizing functions on base functions (e.g. of type numeric or integer). when 1 of both arguments has customclass type, r automatically redirects function instead of default function.
how r chooses method dispatch discussed in details section of ?base::ops
the classes of both arguments considered in dispatching member of group. each argument vector of classes examined see if there matching specific (preferred) or 'ops' method. if method found 1 argument or same method found both, used. if different methods found, there warning 'incompatible methods': in case or if no method found either argument internal method used.
if customclass1
, customclass2
related, can use virtual class allow operations using 2 different classes. example, can mix posixct
, posixlt
because both inherit posixt
. documented in ?datetimeclasses
:
"posixct"
more convenient including in data frames, ,"posixlt"
closer human-readable forms. virtual class"posixt"
exists both of classes inherit: used allow operations such subtraction mix two
for example:
class(pct <- sys.time()) # [1] "posixct" "posixt" sys.sleep(1) class(plt <- as.posixlt(sys.time())) # [1] "posixlt" "posixt" plt - pct # time difference of 1.001677 secs
if classes aren't related in way, there's information in answers emulating multiple dispatch using s3 “+” method - possible?.
Comments
Post a Comment