From cstrato at aon.at  Sun Dec 23 23:36:34 2007
From: cstrato at aon.at (cstrato)
Date: Sun, 23 Dec 2007 23:36:34 +0100
Subject: [Rd] Problem with initialize of S4 classes
Message-ID: <476EE2F2.4010500@aon.at>

Dear all

Below is the code for "scriptPreFilter.R" which gives the following result:
 > source("scriptPreFilter.R")
 > prefltr <- new("PreFilter", mad=c(0.5,0.01))
[1] "------initialize:PreFilter------"
[1] "------initialize:Filter------"
 > str(prefltr)
Formal class 'PreFilter' [package ".GlobalEnv"] with 2 slots
  ..@ mad       :List of 2
  .. ..$ cutoff : num 0.5
  .. ..$ epsilon: num 0.01
  ..@ numfilters: num 1

It seems that everything is ok, the results are as expected.

However, my problem is that copying the identical code to my package 
results in an error:
 > prefltr <- new("PreFilter", mad=c(0.5,0.01))
[1] "------setValidity:Filter------"
Error in validObject(.Object) :
  invalid class "PreFilter" object: invalid object for slot "mad" in 
class "PreFilter": got class "numeric", should be or extend class "list"

The following code avoids the error and gives the result:
 > prefltr <- new("PreFilter", mad=list(0.5,0.01))
[1] "------setValidity:Filter------"
[1] "------setValidity:PreFilter------"
 > str(prefltr)
Formal class 'PreFilter' [package "xps"] with 11 slots
  ..@ mad        :List of 2
  .. ..$ : num 0.5
  .. ..$ : num 0.01
  ..@ numfilters : num 0

This is only partly correct, e.g. numfilters is 0.

Only the following code gives the correct result:
 > prefltr <- new("PreFilter")
 > madFilter(prefltr) <- c(0.5,0.01)
 > str(prefltr)
Formal class 'PreFilter' [package "xps"] with 11 slots
  ..@ mad        :List of 2
  .. ..$ cutoff : num 0.5
  .. ..$ epsilon: num 0.01
  ..@ numfilters : num 1

As you see, the loading "scriptPreFilter.R" calls method initialize but 
not setValidity.
In contrast, loading my package as library calls setValidity but not 
initialize.

My question is:
- Why can the identical code behave differently when put in a package?
- How can I ensure, that initialize gets also called in my package?

 > sessionInfo()
R version 2.6.1 (2007-11-26)
i386-apple-darwin8.10.1

locale:
C

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] xps_0.4.0

loaded via a namespace (and not attached):
[1] rcompgen_0.1-17

Best regards and Merry Christmas
Christian
_._._._._._._._._._._._._._._._
C.h.i.s.t.i.a.n S.t.r.a.t.o.w.a
V.i.e.n.n.a       A.u.s.t.r.i.a
e.m.a.i.l:    cstrato at aon.at
_._._._._._._._._._._._._._._._


------- BEGIN: scriptPreFilter.R ---------
setClass("Filter",
   representation(numfilters = "numeric"),
   prototype(numfilters = 0)
)

setClass("PreFilter",
   representation(mad = "list"),
   contains=c("Filter"),
   prototype(mad = list())
)

setGeneric("madFilter",   function(object) standardGeneric("madFilter"))
setGeneric("madFilter<-", function(object, value) 
standardGeneric("madFilter<-"))

"initialize.Filter" <- function(.Object, ...)
{
   print("------initialize:Filter------")
   .Object <- callNextMethod(.Object, ...)
   .Object
}
setMethod("initialize", "Filter", initialize.Filter)

setValidity("Filter",
   function(object) {
      print("------setValidity:Filter------")
      msg <- NULL
      if (is.null(msg)) TRUE else msg
   }
)

"initialize.PreFilter" <- function(.Object, mad = list(), ...)
{
   print("------initialize:PreFilter------")
   .Object at numfilters <- 0
   if (length(mad)) madFilter(.Object) <- unlist(mad)
   .Object <- callNextMethod(.Object, ...)
   .Object
}
setMethod("initialize", "PreFilter", initialize.PreFilter)

setValidity("PreFilter",
   function(object) {
      print("------setValidity:PreFilter------")
      msg <- NULL
      if (is.null(msg)) TRUE else msg
   }
)

setMethod("madFilter", signature(object="PreFilter"),
   function(object) object at mad
)

setReplaceMethod("madFilter", signature(object="PreFilter", 
value="numeric"),
   function(object, value) {
      if (length(value) == 1) {
         value[2] <- 0.01
      } else if (length(value) != 2) {
         stop(paste(sQuote("mad"), "must have <cutoff,epsilon>"))
      }#if

      if (length(object at mad) == 0) {
         object at numfilters <- object at numfilters + 1
      }#if
      object at mad <- list(cutoff  = as.double(value[1]),
                         epsilon = as.double(value[2]))
      return(object)
   }
)
------- END: scriptPreFilter.R ---------



[Rd] Problem with initialize of S4 classes
cstrato