>>>>> "TR" == Troy Robertson <troy.robert...@aad.gov.au> >>>>> on Thu, 7 Oct 2010 13:50:49 +1100 writes:
>> >> On 10/06/2010 06:12 PM, Troy Robertson wrote: >> > Hi all, >> > >> > After no replies to my previous message I thought I might show some >> > code to demonstrate the change and again seek any >> explanation for the >> > error now thrown by my code after upgrading from 2.10.1 to 2.11.1. >> > >> > Thanks >> > Troy >> > -------------------------------------------------------- >> > setClass("PortableObject", >> > representation(test1 = "character"), >> > >> > prototype( test1 = ""), >> > contains = ".environment" >> > ) >> > >> > setMethod("initialize", "PortableObject", >> > function(.Object, ..., .xData=new.env(parent=emptyenv())) { >> > .Object <- callNextMethod(.Object, ..., >> .xData=.xData) >> > >> > .obj...@test1 <- "Foo" >> > # Following line works under 2.10.1 but now throws >> > # Error: evaluation nested too deeply: >> infinite recursion / options(expressions=)? >> > #####.Object[["test2"]] <- "Bar" >> > # The following does what I want though >> > .Object$test3 <- "Baa" >> > >> > return(.Object) >> > } >> > ) >> > >> > e <- new("PortableObject") >> >> The explicit example does help -- it's clear what bug you are >> encountering. Here's the code in R-2.10 >> >> > selectMethod("[[<-", ".environment") >> Method Definition: >> >> function (x, i, j, ..., value) >> { >> call <- sys.call() >> call[[2]] <- x...@.data >> eval.parent(call) >> x >> } >> >> >> and 2.11.1 >> >> > selectMethod("[[<-", ".environment") >> Method Definition: >> >> function (x, i, j, ..., value) >> { >> .local <- function (x, i, j, ..., exact = TRUE, value) >> { >> call <- sys.call() >> call[[2]] <- x...@.data >> eval.parent(call) >> x >> } >> .local(x, i, j, ..., value = value) >> } >> >> Apparently the 'exact' argument has been added, and because >> the method signature differs from the generic, a .local >> function is created. That 'sys.call()' originally returned >> the environment in which the generic was called, but now it >> returns the environment in which .local is defined. And so >> eval() keeps evaluating .local(). This I think is a bug. TR> Yes, afer the email from William Dunlop, I found this difference in the methods between 2.10.1 and 2.11.1 TR> I had a play and by adding my own method to overload "[[<-" for my PortableObject was able to reinstate the original functionality without the recursive error. TR> setMethod("[[<-", "PortableObject", TR> function (x, i, j, ..., value) TR> { TR> call <- sys.call() TR> call[[2]] <- x...@.data TR> eval.parent(call) TR> x TR> } TR> ) >> >> For what it's worth, if I were interested in minimizing >> copying I would set up initialize so that it ended with >> callNextMethod(<...>), on the hopes that the method >> eventually called would take care not to make too many copies >> on slot assignment. >> >> Martin >> TR> Hmmm, not sure what you mean here? My code passes objects such as these as parameters to other S4 classes which alter their data. If the .xData slot is used then I have no need to return the object. No copy-on-change is performed but data held by the PortableObject is modified. This speeds up my execution time by a LARGE amount. TR> I could very well have things all arse-about, having come from a Java OO background, but this is the only way I have been able to create a pass-by-reference paradigm using S4 classes. Any suggestions for alternative solutions would be greatfully received. TR> Troy R 2.12.2 (currently beta) has in its NEWS : o A facility for defining reference-based S4 classes (in the OOP style of Java, C++, etc.) has been added experimentally to package methods; see ?ReferenceClasses. ---> Please get R-2.12.2 beta and tell here about your experiences. John Chambers (you have in CC) will be particularly interested in your feedback. Martin Maechler, ETH Zurich ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel