Hi again Jeff... Jeffrey Spies <[EMAIL PROTECTED]> writes:
> Thanks for the response, Martin. While the solutions offered update the > object appropriately, we wouldn't get the desired return value (a string > followed by the counter, "unique_1") when the methods are called. Do you > know a way of dealing with this? I don't have a solution for you, other than calling a method to increment the counter and a second to retrieve the current name. Here's another unsatisfactory solution... setClass("Stateful", representation=representation( state="environment")) setMethod("initialize", "Stateful", function(.Object, ..., state=new.env(parent=emptyenv())) { state[["count"]] <- 0 callNextMethod(.Object, ..., state=state) }) setGeneric("state", function(x) standardGeneric("state")) setMethod("state", "Stateful", function(x) [EMAIL PROTECTED]) setGeneric("uname", function(x, ...) standardGeneric("uname")) setMethod("uname", "Stateful", function(x, ...) { state <- state(x) assign("count", state[["count"]] + 1, state) paste("unique", state[["count"]], sep="_") }) > s <- new("Stateful") > uname(s) [1] "unique_1" > uname(s) [1] "unique_2" ... and the reason why this will be surprising to users > s <- t <- new("Stateful") > uname(s) [1] "unique_1" > uname(s) [1] "unique_2" > uname(t) # hey, this is the first time I referenced t! [1] "unique_3" I guess this points to maybe some subtle issues with what you're trying to do, arising from a tension between pass-by-value and pass-by-reference (or to my own fuzzy-headed thinking). For instance, supppose you've implemented your 'uniqueName' function to update the object but return the unique name, and you've done it without using an environment like above, so that each instance of MyMatrix has its own counter. Say you have an instance x of 'MyMatrix' in the global environment. You pass it to a function. R's pass-by-value means it gets copied to a local variable in the function, say x1. The function queries 'uniqueName', modifying x1. But x in the global environment is unchanged. So the next time this function is invoked, it gets the same 'unique' name. Is this what you were expecting? These are just my two cents, of course, maybe others have different ideas. Martin > Jeff. > > > Martin Morgan wrote: >> >> Hi Jeff -- >> >> two different scenarios are to overwrite the current object, along the >> lines of >> >> y <- uniquify(y) >> >> where uniquify is a method like createUniqueName but returns the >> (modified) instance rather than unique name >> >> setMethod('uniquify', 'MyMatrix', function(x) { >> [EMAIL PROTECTED] <- # something unique >> x >> }) >> >> The second is a replacement method, along the lines of >> >> setGeneric("uniqueCount<-", >> function(x, ..., value) standardGeneric("uniqueCount<-")) >> >> setReplaceMethod("uniqueCount", >> signature=c(x="MyMatrix", value="numeric"), >> function(x, ..., value) { >> [EMAIL PROTECTED] <- value >> x >> }) >> >> uniqueCount(x) <- uniqueCount(x) + 1 >> x # now modified >> >> This is untested psuedo-code, so I hope it's right enough to get you >> going. >> >> Martin >> >> Jeffrey Spies <[EMAIL PROTECTED]> writes: >> >>> Howdy all, >>> >>> I have a problem that I'd like some advice/help in solving---it has to do >>> with R's pass-by-value system. I understand the issue, but am wondering >>> if >>> anyone has found a working solution in dealing with it for cases when one >>> wants to modify an object inside of a method, specifically when working >>> with >>> S4. I'm aware that R.oo is able to deal with this using S3, but I'd >>> really >>> rather stick to S4. >>> >>> The basics of what I would like to do are coded below: >>> >>> setClass("MyMatrix", >>> representation( >>> parameters="matrix", >>> uniqueCount="numeric" >>> ), >>> prototype( >>> parameters=matrix(numeric(0),0,0), >>> uniqueCount=1 >>> ) >>> ) >>> >>> setGeneric("createUniqueName", function(object) >>> standardGeneric("createUniqueName")) >>> >>> setMethod("createUniqueName", "MyMatrix", function(object){ >>> retval <- paste("unique_", [EMAIL PROTECTED], sep="") >>> [EMAIL PROTECTED] <- [EMAIL PROTECTED] + 1 >>> return(retval) >>> }) >>> >>> x <- new("MyMatrix", parameters=matrix(0, 2, 2)) >>> createUniqueName(x) # returns "unique_1" >>> x # [EMAIL PROTECTED] is still 1 >>> >>> I understand why this is happening, but am wondering how people in the >>> community have dealt with it, specifically when using S4. Any advice >>> would >>> be appreciated. Also, I am aware that this is somewhat of a silly >>> example, >>> but it should allow you to see what I'm trying to accomplish. >>> >>> Thank you, >>> >>> Jeff. >>> >> > > -- > View this message in context: > http://www.nabble.com/S4-pass-by-value-work-around--tp17997553p18012246.html > Sent from the R help mailing list archive at Nabble.com. > > ______________________________________________ > R-help@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. -- Martin Morgan Computational Biology / Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109 Location: Arnold Building M2 B169 Phone: (206) 667-2793 ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.