From murdoch.duncan at gmail.com  Thu Oct  7 12:58:34 2010
From: murdoch.duncan at gmail.com (Duncan Murdoch)
Date: Thu, 07 Oct 2010 06:58:34 -0400
Subject: [Rd] Recursion error after upgrade
 to	R_2.11.1	[Sec=Unclassified] [Sec=Unclassified]
In-Reply-To: <19629.42447.193180.477102@lynne.math.ethz.ch>
References: <4CAD2EAF.8040505@fhcrc.org>	<42C7503E0B99F248B06BC65E7D2B4E020187DD7258F4@EX2K7-CCR.AAD.GOV.AU>
	<19629.42447.193180.477102@lynne.math.ethz.ch>
Message-ID: <4CADA7DA.7080402@gmail.com>

On 07/10/2010 6:49 AM, Martin Maechler wrote:
>>>>>> "TR" == Troy Robertson <Troy.Robertson at 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)
>     >> >
>     >> >                 .Object at 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 at .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 at .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 at .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 :

Just pointing out a typo:  the version of the beta is 2.12.0.

Duncan Murdoch

> 
>     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 at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] Recursion error after upgrade to R_2.11.1 [Sec=Unclassified] [Sec=Unclassified]
Duncan Murdoch