Dear R gurus, I am trying to create a nicer API interface for some R modules I have written. Here, I heavily rely on S3 method dispatch mechanics and makeActiveBinding() function I have discovered that I apparently can't dispatch on function call operator (). While .Primitive("(") exists, which leads me to believe that things like x(...) are internally translated to .Primitive("(")(x, ...), I can't seem to do something like: x <- integer() class(x) <- "testclass" "(.testclass" <- function(o, x, y) print(paste(x, y)) x(1, 2) Similar code does work for other operators like "[". A workaround I have discovered is to make x a function from the beginning and then extend the functionality by via S3 methods. Unfortunately, it does not allow me to do something I'd really like to - use syntax like this: x(...) <- y For this, I'd need to dispatch on something like "(<-.testclass" <- function(x, arglist, value) Currently, I am using the index operator for this (i.e. x[...] <- y) - it works nicely, but I'd prefer the () syntax, if possible. Does anyone know a way to do this? -- View this message in context: http://r.789695.n4.nabble.com/Method-dispatch-for-function-call-operator-tp3215381p3215381.html Sent from the R help mailing list archive at Nabble.com.
On 11-01-13 3:09 AM, Taras Zakharko wrote:> > Dear R gurus, > > I am trying to create a nicer API interface for some R modules I have > written. Here, I heavily rely on S3 method dispatch mechanics and > makeActiveBinding() function > > I have discovered that I apparently can't dispatch on function call > operator (). While .Primitive("(") exists, which leads me to believe that > things like x(...) are internally translated to .Primitive("(")(x, ...), I > can't seem to do something like:The "(" function is not a function call operator. It's essentially a no-op. I believe its only purpose is to help in deparsing, so that things like (x + y) would deparse in the same way as entered.> > x<- integer() > class(x)<- "testclass" > "(.testclass"<- function(o, x, y) print(paste(x, y)) > x(1, 2) > > Similar code does work for other operators like "[". > > A workaround I have discovered is to make x a function from the beginning > and then extend the functionality by via S3 methods. Unfortunately, it does > not allow me to do something I'd really like to - use syntax like this: > > x(...)<- yYou can use this syntax by defining a function `x<-` <- function(...) {} and it could be an S3 method, but it is a completely separate object from x. Duncan Murdoch> > For this, I'd need to dispatch on something like > > "(<-.testclass"<- function(x, arglist, value) > > Currently, I am using the index operator for this (i.e. x[...]<- y) - it > works nicely, but I'd prefer the () syntax, if possible. > > Does anyone know a way to do this? >
The details here are much more appropriate for R-devel, but please check the help pages for "(" and "[", and note - "[" is generic and "(" is not. - the primitive `(` is used to implement constructions such as (x <- pi) and not x(...). The special handling of operators such as "[" is part of the parser, and you are guessing incorrectly how function calls are parsed. (Note to Duncan Murdoch whose reply came in whilst I was writig this: "(" is essentially a no-op, but it does turn visibility on, something often used with assignments.) On Thu, 13 Jan 2011, Taras Zakharko wrote:> > Dear R gurus, > > I am trying to create a nicer API interface for some R modules I have > written. Here, I heavily rely on S3 method dispatch mechanics and > makeActiveBinding() function > > I have discovered that I apparently can't dispatch on function call > operator (). While .Primitive("(") exists, which leads me to believe that > things like x(...) are internally translated to .Primitive("(")(x, ...), I > can't seem to do something like: > > x <- integer() > class(x) <- "testclass" > "(.testclass" <- function(o, x, y) print(paste(x, y)) > x(1, 2) > > Similar code does work for other operators like "[". > > A workaround I have discovered is to make x a function from the beginning > and then extend the functionality by via S3 methods. Unfortunately, it does > not allow me to do something I'd really like to - use syntax like this: > > x(...) <- y > > For this, I'd need to dispatch on something like > > "(<-.testclass" <- function(x, arglist, value) > > Currently, I am using the index operator for this (i.e. x[...] <- y) - it > works nicely, but I'd prefer the () syntax, if possible. > > Does anyone know a way to do this? > > -- > View this message in context: http://r.789695.n4.nabble.com/Method-dispatch-for-function-call-operator-tp3215381p3215381.html > Sent from the R help mailing list archive at Nabble.com. > > ______________________________________________ > 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