On Tue, 29 Jan 2008, Herve Pages wrote: > Hi again, > > Here is an example of an annoyance that I think is directly related to the > problem with new("externalptr"). When you try to extend the "externalptr" > class:
You don't wnat to do that for the same reason you don't want to do it with environments: Like environment external pointers are reference objects, so things like unclass and other attribute changes end up being destructive. Create the thing you want as a list wrapper around the external pointer. You'll be a lot happier with the result in the long run. luke > > > setClass("ExternalInteger", contains="externalptr") > [1] "ExternalInteger" > > then every call to new("ExternalInteger") will return the same instance too. > > I've tried to define an "initialize" method for "ExternalInteger" objects, > but, > whatever I do, I end up with the same "ExternalInteger" instance. So in the > end > I had to define the "ExternalInteger" class this way: > > > setClass("ExternalInteger", representation(xp="externalptr")) > > even if I'd really like to be able to use the "is a" semantic and not the > "has a" > semantic. > > Then I use my xp_new() C routine (see previous post) for initializing the xp > slot: > > setMethod("initialize", "ExternalInteger", > function(.Object, ...) > { > [EMAIL PROTECTED] <- .Call("xp_new") > ... > .Object > } > ) > > Then everytime I need to pass an "ExternalInteger" instance x to a C routine, > I need to perform one extra step to reach the externalptr (need to pass > [EMAIL PROTECTED] to > the routine instead of x itself). > > So unfortunately, things are quite ugly and more painful than necessary. > > Thanks, > H. > > > Herve Pages wrote: >> Hi, >> >> It seems that new("externalptr") is always returning the same instance, and >> not a new one as one would expect from a call to new(). Of course this is >> hard >> to observe: >> >> > new("externalptr") >> <pointer: (nil)> >> > new("externalptr") >> <pointer: (nil)> >> >> since not a lot of details are displayed. >> >> For example, it's easy to see that 2 consecutive calls to new("environment") >> create different instances: >> >> > new("environment") >> <environment: 0xc89d10> >> > new("environment") >> <environment: 0xc51248> >> >> But for new("externalptr"), I had to use the following C routine: >> >> SEXP sexp_address(SEXP s) >> { >> SEXP ans; >> char buf[40]; >> >> snprintf(buf, sizeof(buf), "%p", s); >> PROTECT(ans = NEW_CHARACTER(1)); >> SET_STRING_ELT(ans, 0, mkChar(buf)); >> UNPROTECT(1); >> return ans; >> } >> >> Then I get: >> >> > .Call("sexp_address", new("externalptr")) >> [1] "0xde2ce0" >> > .Call("sexp_address", new("externalptr")) >> [1] "0xde2ce0" >> >> Isn't that wrong? >> >> I worked around this problem by writing the following C routine: >> >> SEXP xp_new() >> { >> return R_MakeExternalPtr(NULL, R_NilValue, R_NilValue); >> } >> >> so I can create new "externalptr" instances from R with: >> >> .Call("xp_new") >> >> I understand that there is not much you can do from R with an "externalptr" >> instance and that you will have to manipulate them at the C level anyway. >> But since new("externalptr") exists and seems to work, wouldn't that be >> better if it was really creating a new instance at each call? >> >> Thanks! >> H. >> >> ______________________________________________ >> R-devel@r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel >> > > ______________________________________________ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > -- Luke Tierney Chair, Statistics and Actuarial Science Ralph E. Wareham Professor of Mathematical Sciences University of Iowa Phone: 319-335-3386 Department of Statistics and Fax: 319-335-3017 Actuarial Science 241 Schaeffer Hall email: [EMAIL PROTECTED] Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel