Janko Thyson
2011-May-04 19:39 UTC
[Rd] Reference Classes: replacing '.self' with an .Rda image of '.self' from within a method? (was replacing '.self' with an .Rda image of '.self' from within a method?)
Sorry guys, but I chose a really stupid name before (no "reference classes"). Hope it's okay to re-post. Cheers, Janko >>> ORIGINAL MESSAGE <<< Dear list, Is it possible to update or reassign '.self' with an image of '.self' (e.g. a locally stored .Rda file) from within a method? I know that this might sound akward, but here's the use case: 1) Ref Class Definition setRefClass(Class="Test", fields=list(A="character", B="character"), methods=list(importImage=function(path){ variable <- load(path) expr <- paste("assign('", variable, "',", variable, ", envir=.self)", sep="") eval(parse(text=expr)) } ) 2) Initialize Method Definition setMethod( f="initialize", signature=signature(.Object="Test"), definition=function( .Object, path=NULL ){ obj <- callNextMethod(.Object) if(!is.null(path){ obj$importImage(path=path) } return(obj) } 3) Intended and "Extended" Use Method 'importImage' was originally intended to read either an object of name 'A' or 'B' from a respective path and overwrite the respective fields in an obj of class 'Test'. Now I wondered how I could "reassign"/update the object of class 'Test' itself by reading a respective .Rda image of an object of class 'Test' from within 'obj$importImage()'. The way I've written 'importImage()', it did not work. Yet I wonder if it's possible. 4) My Workaround (but I'm looking for something more elegantly) In the class definition: [...] methods=list(importImage=function(path){ variable <- load(path) if(variable != ".self"){ expr <- paste("assign('", variable, "',", variable, ", envir=.self)", sep="") eval(parse(text=expr)) return(TRUE) } else { return(.self) } }) [...] In the initialize method: setMethod( f="initialize", signature=signature(.Object="Test"), definition=function( .Object, path=NULL ){ obj <- callNextMethod(.Object) if(!is.null(path){ rslt <- obj$importImage(path=path) if(!is.logical(rslt)){ obj <- rslt } } return(obj) } Thanks for any comments, Janko
John Chambers
2011-May-04 21:46 UTC
[Rd] Reference Classes: replacing '.self' with an .Rda image of '.self' from within a method? (was replacing '.self' with an .Rda image of '.self' from within a method?)
It makes no sense to replace the .self field: that field is initialized to be a reference to the object. If you change it, it's no longer that reference. There are many things wrong with your example, so it's better to take a very simple version: > mkTest <- setRefClass("test",fields = list(a = "numeric")) > x <- mkTest$new(a=1:10) Now suppose we replace the .self field with another one: > y <- mkTest$new(a = 11:20) > x$.self <- y$.self At this point x is messed up and does not correspond to the .self field: > x$a [1] 1 2 3 4 5 6 7 8 9 10 > x$.self$a [1] 11 12 13 14 15 16 17 18 19 20 The same problem results no matter how you change the field. The only difference with a method is that you do get a warning message. > pseudoSelf <- as.environment(list(a = 5)) > x$.self <- pseudoSelf > x$a [1] 1 2 3 4 5 6 7 8 9 10 > x$.self$a [1] 5 > mkTest$methods(screwup = function(newSelf) .self <<- newSelf) Warning message: In .checkFieldsInMethod(def, fieldNames, allMethods) : Non-local assignment to non-field names (possibly misspelled?) .self <<- newSelf ( in method "screwup" for class "test") > x <- mkTest$new(a=1:10) > x$screwup(pseudoSelf) > x$a [1] 1 2 3 4 5 6 7 8 9 10 > x$.self$a [1] 5 We need to make the .self field read-only. On 5/4/11 12:39 PM, Janko Thyson wrote:> Sorry guys, > > but I chose a really stupid name before (no "reference classes"). > > Hope it's okay to re-post. > > Cheers, > Janko > > >>> ORIGINAL MESSAGE <<< > > Dear list, > > Is it possible to update or reassign '.self' with an image of '.self' > (e.g. a locally stored .Rda file) from within a method? > > I know that this might sound akward, but here's the use case: > 1) Ref Class Definition > setRefClass(Class="Test", > fields=list(A="character", B="character"), > methods=list(importImage=function(path){ > variable <- load(path) > expr <- paste("assign('", variable, "',", variable, ", envir=.self)", > sep="") > eval(parse(text=expr)) > } > ) > 2) Initialize Method Definition > setMethod( > f="initialize", > signature=signature(.Object="Test"), > definition=function( > .Object, > path=NULL > ){ > obj <- callNextMethod(.Object) > if(!is.null(path){ > obj$importImage(path=path) > } > return(obj) > } > 3) Intended and "Extended" Use > Method 'importImage' was originally intended to read either an object of > name 'A' or 'B' from a respective path and overwrite the respective > fields in an obj of class 'Test'. > Now I wondered how I could "reassign"/update the object of class 'Test' > itself by reading a respective .Rda image of an object of class 'Test' > from within 'obj$importImage()'. > The way I've written 'importImage()', it did not work. Yet I wonder if > it's possible. > 4) My Workaround (but I'm looking for something more elegantly) > In the class definition: > [...] > methods=list(importImage=function(path){ > variable <- load(path) > if(variable != ".self"){ > expr <- paste("assign('", variable, "',", variable, ", envir=.self)", > sep="") > eval(parse(text=expr)) > return(TRUE) > } else { > return(.self) > } > }) > [...] > > In the initialize method: > setMethod( > f="initialize", > signature=signature(.Object="Test"), > definition=function( > .Object, > path=NULL > ){ > obj <- callNextMethod(.Object) > if(!is.null(path){ > rslt <- obj$importImage(path=path) > if(!is.logical(rslt)){ > obj <- rslt > } > } > return(obj) > } > > Thanks for any comments, > Janko > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >