[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?)

John Chambers jmc at r-project.org
Wed May 4 23:46:38 CEST 2011


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
>



More information about the R-devel mailing list