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
>