From Troy.Robertson at aad.gov.au  Thu Oct  7 04:50:49 2010
From: Troy.Robertson at aad.gov.au (Troy Robertson)
Date: Thu, 7 Oct 2010 13:50:49 +1100
Subject: [Rd] Recursion error after upgrade to
	R_2.11.1	[Sec=Unclassified] [Sec=Unclassified]
In-Reply-To: <4CAD2EAF.8040505@fhcrc.org>
Message-ID: <42C7503E0B99F248B06BC65E7D2B4E020187DD7258F4@EX2K7-CCR.AAD.GOV.AU>

>
> 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.

Yes, afer the email from William Dunlop, I found this difference in the methods between 2.10.1 and 2.11.1
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.

setMethod("[[<-", "PortableObject",
        function (x, i, j, ..., value)
        {
                call <- sys.call()
                call[[2]] <- x at .Data
                eval.parent(call)
                x
        }
)

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

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.

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.

Troy

> >
> > alterEGo <- function(o = "EPOCObject") {
> >         o at test1 <- "Boo"
> >
> >         # Following line works under 2.10.1 but now throws
> >         # Error: evaluation nested too deeply: infinite
> recursion / options(expressions=)?
> >         ####o[["test2"]] <- "Who"
> >         # The following does what I want though
> >         o$test3 <- "Hoo"
> >
> >         # NOTE: No return
> > }
> >
> > alterEGo(e)
> > e at test1
> > e$test2
> > e[["test3"]]
> > e at .xData[["test3"]]
> >
___________________________________________________________________________

    Australian Antarctic Division - Commonwealth of Australia
IMPORTANT: This transmission is intended for the addressee only. If you are not the
intended recipient, you are notified that use or dissemination of this communication is
strictly prohibited by Commonwealth law. If you have received this transmission in error,
please notify the sender immediately by e-mail or by telephoning +61 3 6232 3209 and
DELETE the message.
        Visit our web site at http://www.antarctica.gov.au/
___________________________________________________________________________



[Rd] Recursion error after upgrade to R_2.11.1 [Sec=Unclassified] [Sec=Unclassified]
Troy Robertson