Re: [Rd] Ref Classes: bug with using '.self' within initialize methods?

From: John Chambers <jmc_at_r-project.org>
Date: Sat, 02 Jul 2011 13:43:16 -0700

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
>



R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel Received on Sat 02 Jul 2011 - 20:45:53 GMT

This quarter's messages: by month, or sorted: [ by date ] [ by thread ] [ by subject ] [ by author ]

All messages

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Sun 03 Jul 2011 - 13:40:06 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel. Please read the posting guide before posting to the list.

list of date sections of archive