[Rd] Ref Classes: bug with using '.self' within initialize methods?
John Chambers
jmc at r-project.org
Sat Jul 2 22:43:16 CEST 2011
I don't have anything to suggest on your specific example but perhaps
these two notes are relevant.
1. As is mentioned in the documentation, it's generally a bad idea to
write S4 initialize() methods for reference classes, rather than
reference class methods for $initialize():
"a reference method is recommended rather than a method for the S4
generic function initialize(), because some special initialization is
required for reference objects _before_ the initialization of fields."
2. In a simple example, there is no problem using .self in a
$initialize() method.
######
ss <- setRefClass("ss", fields = c("a", "b", "c"),
methods = list(
initialize = function(...) {
callSuper(...)
.self$b <- .self$a
},
check = function()
.self$c <- .self$a
))
s1 <- ss$new(a=1)
s1$check()
stopifnot(identical(s1$a, 1), identical(s1$a, s1$b),
identical(s1$a, s1$c))
#######
On 6/29/11 9:36 AM, Janko Thyson wrote:
> Dear list,
>
> I'm wondering if the following error I'm getting is a small bug in the
> Reference Class paradigm or if it makes perfect sense.
>
> When you write an explicit initialize method for a Ref Class, can you
> then make use of '.self' WITHIN this initialize method just as you would
> once an object of the class has actually been initialized?
> Because it seems to me that you can not.
>
> Below is an example that shows that calling '.self$someInitFoo()' within
> the initialize method for 'MyClass' does not work (see section "METHODS"
> in example below). Instead I have to go with
> 'someInitFooRefInner(.self=.Object, ...)' (see section "UPDATED METHOD"
> in example below). Yet, this is only possible because there actually IS
> such a method (I try to stick to the recommendations at ?setRefClass
> where it says: "Reference methods should be kept simple; if they need to
> do some specialized *R* computation, that computation should use a
> separate *R* function that is called from the reference method")
>
> The same problem occurs when, say 'someInitFoo()' calls yet another Ref
> Class method (as is the case in the example below with a call to
> '.self$someFoo()').
>
> Is this a desired behavior?
>
> Thanks for any clarifying comments!
> Janko
>
> ##### CODE EXAMPLE #####
>
> # CLASSES
> setRefClass(
> Class="MyVirtual",
> contains=c("VIRTUAL"),
> methods=list(
> initialize=function(...){
> callSuper(...)
> return(.self)
> },
> someInitFoo=function(flds, ...){
> someInitFooRefInner(
> .self=.self,
> flds=flds
> )
> }
> )
> )
> GENERATOR<- setRefClass(
> Class="MyClass",
> contains=c("MyVirtual"),
> fields=list(
> A="character",
> B="numeric"
> ),
> methods=list(
> someFoo=function(...){
> someFooRefInner(.self=.self, ...)
> }
> )
> )
> # /
>
> # GENERICS
> setGeneric(name="someInitFooRefInner",
> def=function(.self, ...) standardGeneric("someInitFooRefInner"),
> signature=c(".self")
> )
> setGeneric(name="someFooRefInner",
> def=function(.self, ...) standardGeneric("someFooRefInner"),
> signature=c(".self")
> )
> # /
>
> # METHODS
> setMethod(
> f="someInitFooRefInner",
> signature=signature(.self="MyVirtual"),
> definition=function(.self, flds, ...){
> print("Trying to call '.self$someFoo()")
> try(.self$someFoo())
> print("Trying to call 'someFooRefInner(.self=.self)")
> try(someFooRefInner(.self=.self))
> return(flds)
> }
> )
> setMethod(
> f="someFooRefInner",
> signature=signature(.self="MyVirtual"),
> definition=function(.self, ...){
> print("hello world!")
> }
> )
> setMethod(
> f="initialize",
> signature=signature(.Object="MyVirtual"),
> definition=function(.Object, GENERATOR=NULL, ...){
> # MESSAGE
> if(class(.Object) == "MyVirtual"){
> cat(paste("initializing object of class '", class(.Object),
> "'",
> sep=""), sep="\n")
> } else {
> cat(paste("initializig object of class'", class(.Object),
> "' inheriting from class 'MyVirtual'", sep=""), sep="\n")
> }
> # /
> # GET GENERATOR OBJECT
> if(is.null(GENERATOR)){
> GENERATOR<- getRefClass(class(.Object))
> }
> flds<- names(GENERATOR$fields())
> .Object$someInitFoo(
> flds=flds,
> ...
> )
> return(.Object)
> }
> )
> # /
>
> x<- GENERATOR$new()
>
> # UPDATED METHOD
> setMethod(
> f="initialize",
> signature=signature(.Object="MyVirtual"),
> definition=function(.Object, GENERATOR=NULL, ...){
> # MESSAGE
> if(class(.Object) == "MyVirtual"){
> cat(paste("initializing object of class '", class(.Object),
> "'",
> sep=""), sep="\n")
> } else {
> cat(paste("initializig object of class'", class(.Object),
> "' inheriting from class 'MyVirtual'", sep=""),
> sep="\n")
> }
> # /
> # GET GENERATOR OBJECT
> if(is.null(GENERATOR)){
> GENERATOR<- getRefClass(class(.Object))
> }
> flds<- names(GENERATOR$fields())
> someInitFooRefInner(.self=.Object, flds=flds, ...)
> return(.Object)
> }
> )
> # /
>
> x<- GENERATOR$new()
>
> [[alternative HTML version deleted]]
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
More information about the R-devel
mailing list