[R] How to: initialize, setValidity, copy-constructor

Renaud Gaujoux renaud at mancala.cbio.uct.ac.za
Thu Jul 9 17:30:01 CEST 2009


Hello list,

I'm having troubles setting up a basic calss hierarchy with S4.
Here is a simplified schema of what I'd like to do:

- Two classes: A and B that extends A
- Ensure that the slots added by B are consistent with the slots of A
- Let A initialize itself (I'm not supposed to know the internal cooking 
of A)
- By default set the slots of B based on the slots that A initialized

Another question is: what is the recommended way of implementing a 
copy-constructor in R?

I know that all of this is easily done in C++. The constructor of each 
class is called recursively back-up to the root class. Validity checks 
can be performed after/during associated initialization. 
Copy-constructor are basics in C++.

Here below is a piece of code that I thought would work (but it does 
not... therefore my post), what's wrong with it?
I think the main issue is when is the validity check performed: why is 
it performed before the end of the initialize method?

Thank you for your help.
Renaud

# define class A with a single numeric slot
setClass('A', representation(a='numeric'))

# define class B that extends class A, adding another numeric slot
setClass('B', representation('A', b='numeric'))
# we want for example to ensure that slots a and b have the same length
setValidity('B',
function(object){
cat("*** B::validate ***\n")
print(object)
cat("*****************\n")
if( length(object at a) != length(object at b) ) return('Inconsistent lengths')
TRUE
}
)
# As a default behaviour if b is not provided, we want slot b to be 
equal to slot a
setMethod('initialize', 'B',
function(.Object, b, ...){
cat("*** B::initialize ***\n")
print(.Object)

# Let the superclass (A) initialize itself via callNextMethod
# I thought it would only do that: initialize and optionnaly validate 
the class A part of the object
#But it generates an ERROR: apparently it calls the validation method of B,
# before leaving me a chance to set slot b to a valid value
.Object <- callNextMethod(.Object, ...)

# now deal with the class B part of the object
cat("*** Test missing b ***\n")
if( missing(b) ){
cat("*** b is MISSING ***\n")
b <- .Object at a
}

# set slot b
.Object at b <- b

.Object
}
)

### Testing

# empty A: OK
aObj <- new('A')
aObj

# class A with some data: OK
aObj <- new('A', a=c(1,2) )
aObj

# empty B: OK
bObj <- new('B')
bObj

# initialize B setting the slot of class A: ERROR
bObj <- new('B', a=c(1,2))

# initialize B setting only the slot class B: OK!! Whereas it produces a 
non valid object.
bObj <- new('B', b=c(1,2))
bObj

######### RESULTS:

 > # empty A: OK
 > aObj <- new('A')
 > aObj
An object of class “A”
Slot "a":
numeric(0)

 >
 > # class A with some data: OK
 > aObj <- new('A', a=c(1,2) )
 > aObj
An object of class “A”
Slot "a":
[1] 1 2

 >
 > # empty B: OK
 > bObj <- new('B')
*** B::initialize ***
An object of class “B”
Slot "b":
numeric(0)

Slot "a":
numeric(0)

*** Test missing b ***
*** b is MISSING ***
 > bObj
An object of class “B”
Slot "b":
numeric(0)

Slot "a":
numeric(0)

 >
 > # initialize B setting the slot of class A: ERROR
 > bObj <- new('B', a=c(1,2))
*** B::initialize ***
An object of class “B”
Slot "b":
numeric(0)

Slot "a":
numeric(0)

*** B::validate ***
An object of class “B”
Slot "b":
numeric(0)

Slot "a":
[1] 1 2

*****************
Error in validObject(.Object) :
invalid class "B" object: Inconsistent lengths
 >
 > # initialize B setting only the slot class B: OK!! Whereas it creates 
a non valid object.
 > bObj <- new('B', b=c(1,2))
*** B::initialize ***
An object of class “B”
Slot "b":
numeric(0)

Slot "a":
numeric(0)

*** Test missing b ***
 > bObj
An object of class “B”
Slot "b":
[1] 1 2

Slot "a":
numeric(0)



-----------------------------
 > sessionInfo()
R version 2.9.1 (2009-06-26)
x86_64-pc-linux-gnu

locale:
LC_CTYPE=en_ZA.UTF-8;LC_NUMERIC=C;LC_TIME=en_ZA.UTF-8;LC_COLLATE=en_ZA.UTF-8;LC_MONETARY=C;LC_MESSAGES=en_ZA.UTF-8;LC_PAPER=en_ZA.UTF-8;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=en_ZA.UTF-8;LC_IDENTIFICATION=C

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

other attached packages:
[1] Biobase_2.4.1




More information about the R-help mailing list