From maechler at stat.math.ethz.ch  Thu Oct  7 12:49:51 2010
From: maechler at stat.math.ethz.ch (Martin Maechler)
Date: Thu, 7 Oct 2010 12:49:51 +0200
Subject: [Rd] Recursion error after upgrade
	to	R_2.11.1	[Sec=Unclassified] [Sec=Unclassified]
In-Reply-To: <42C7503E0B99F248B06BC65E7D2B4E020187DD7258F4@EX2K7-CCR.AAD.GOV.AU>
References: <4CAD2EAF.8040505@fhcrc.org>
	<42C7503E0B99F248B06BC65E7D2B4E020187DD7258F4@EX2K7-CCR.AAD.GOV.AU>
Message-ID: <19629.42447.193180.477102@lynne.math.ethz.ch>

>>>>> "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 :

    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



[Rd] Recursion error after upgrade to R_2.11.1 [Sec=Unclassified] [Sec=Unclassified]
Martin Maechler