Dear all, what is the proper way to make the assignment operator generic and define methods depending on the class of the assigned value? Best regards Jens Oehlschl?gel P.S. I vaguely remember that this was possible in S+. In R I tried to no avail: # using this like h<-1:3 gives Error: in `<-.default`(h, 1:3) : invalid (do_set) left-hand side to assignment "<-.default" <- get("<-") # using this does fail on subassignments like: h <- 1:3 ; h[1] <- 7 (h still is 1:3) "<-.default" <- function(x, value){ assign(deparse(substitute(x)), value, parent.frame()) invisible(x) } # this seems to work "<-" <- function(x, value){ UseMethod("<-", value) } # whenever the assigned value has class 'ff' I want to do execute something like "<-.ff" <- function(x, value){ y <- clone(value) assign(deparse(substitute(x)), y, parent.frame()) y }> version_ platform i386-pc-mingw32 arch i386 os mingw32 system i386, mingw32 status major 2 minor 6.0 year 2007 month 10 day 03 svn rev 43063 language R version.string R version 2.6.0 (2007-10-03) --
are you looking for "setReplaceMethod"? hth Matthias Jens Oehlschl?gel wrote:> Dear all, > > what is the proper way to make the assignment operator generic and define methods depending on the class of the assigned value? > > Best regards > > > Jens Oehlschl?gel > > P.S. I vaguely remember that this was possible in S+. In R I tried to no avail: > > # using this like h<-1:3 gives Error: in `<-.default`(h, 1:3) : invalid (do_set) left-hand side to assignment > "<-.default" <- get("<-") > > # using this does fail on subassignments like: h <- 1:3 ; h[1] <- 7 (h still is 1:3) > "<-.default" <- function(x, value){ > assign(deparse(substitute(x)), value, parent.frame()) > invisible(x) > } > > # this seems to work > "<-" <- function(x, value){ > UseMethod("<-", value) > } > > # whenever the assigned value has class 'ff' I want to do execute something like > "<-.ff" <- function(x, value){ > y <- clone(value) > assign(deparse(substitute(x)), y, parent.frame()) > y > } > > > >> version >> > _ > platform i386-pc-mingw32 > arch i386 > os mingw32 > system i386, mingw32 > status > major 2 > minor 6.0 > year 2007 > month 10 > day 03 > svn rev 43063 > language R > version.string R version 2.6.0 (2007-10-03) > > -- > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >
Thanks Matthias,> are you looking for "setReplaceMethod"?So far the package I m writing has avoided using anything from S4 and the implications of touching S4 are not clear to me. The package aims on providing an alternative to 'atomic' data stored in ram, i.e. large atomic data stored on disk. I need some advice how to do this maximally performant, which probably means pure S3!? Best regards Jens Oehlschl?gel --
Thanks Simon,> You cannot use S3 here, because you want to dispatch on the *second* > argument."<-" <- function(x, value)UseMethod("<-", value) DOES dispatch on the second argument (see the dispatchsecond example below)> Why don't you take the external pointer approach that many others take > to provide proxy objects to external data? (DB access, mem-mapped > files, cross-language objects, etc.) That allows you to define your > storage semantics very efficiently in C. You can still choose to > define any syntactic sugar you want in either S3 or S4.I AM using the external pointer approach and this works verly well - if one tolerates that the external data is not duplicated when the proxy object is copied. I was wondering however, if it is possible to perfectly mimic R's copying semantics: duplicate external object (and the external pointer) on assignment (or even better only on modify after assignment). Best regards Jens Oehlschl?gel> dispatchsecond <- function(first, second)+ UseMethod("dispatchsecond", second)> > dispatchsecond.default <- function(first, second){+ cat("here default\n") + }> > dispatchsecond.ff <- function(first, second){+ cat("here ff\n") + }> > default <- 1 > ff <- 1 > class(ff) <- "ff" > > dispatchsecond(1,default)here default> dispatchsecond(1,ff)here ff>--
Thank you Brian,> setReplaceMethod() is just syntactic sugar for setting an S4 method on a > replacement function (read the function definition to see so). You can > set S3 replacement methods, and the S4 mechanism just piggy-backs on that.So I understand that setReplaceMethod will not help.> I think the conceptual problem is that the assignment operator does not > actually do any copying: it creates a binding of a symbol to a value. > Any copying which occurs happens when the value is (potentially) changed.I would be even happier if the cloning would only occur on any attempt to change the external pointer / proxy-object.> There is no provision for that to depend on the class (rather than the > type) of the object.Mh, unless the internal copying mechanism would call a clone generic for non-atomic objects> Since external pointers are never duplicated, you > ought to be able to take advantage of that to design the copying semantics > you want.How that? How do I know that any user has assigned/modified the external pointer (or a proxy object containing the external pointer) such that I can invoke the cloning? Best regards Jens Oehlschl?gel --
Thanks Simon,> You cannot use S3 here, because you want to dispatch on the *second* > argument."<-" <- function(x, value)UseMethod("<-", value) DOES dispatch on the second argument (see the dispatchsecond example below)> Why don't you take the external pointer approach that many others take > to provide proxy objects to external data? (DB access, mem-mapped > files, cross-language objects, etc.) That allows you to define your > storage semantics very efficiently in C. You can still choose to > define any syntactic sugar you want in either S3 or S4.I AM using the external pointer approach and this works verly well - if one tolerates that the external data is not duplicated when the proxy object is copied. I was wondering however, if it is possible to perfectly mimic R's copying semantics: duplicate external object (and the external pointer) on assignment (or even better only on modify after assignment). Best regards Jens Oehlschl?gel> dispatchsecond <- function(first, second)+ UseMethod("dispatchsecond", second)> > dispatchsecond.default <- function(first, second){+ cat("here default\n") + }> > dispatchsecond.ff <- function(first, second){+ cat("here ff\n") + }> > default <- 1 > ff <- 1 > class(ff) <- "ff" > > dispatchsecond(1,default)here default> dispatchsecond(1,ff)here ff>--
Reasonably Related Threads
- package incompatibility under 2.5.0 (please respond directly, I am not on r-devel)
- basename returns "." not in filename (PR#13958)
- namespace crash on S3method("as.ff",function)
- Error in substring: invalid multibyte string
- Can saved R object .RData files be loaded by more than one R sessions for read only purpose?