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

2011-07-02 Thread John Chambers
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)
  }
  # /
 

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

2011-06-29 Thread Janko Thyson
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@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel