Define constructors:
setGeneric("A", function(a,b,...) standardGeneric("A"))
setMethod("A", signature(a="missing",b="missing"),
function(a,b,...) A(as.numeric(1:10),...) ## calls the one below
)
setMethod("A", signature(a="A",b="missing"),
function(a,b,...) a
)
setMethod("A", signature(a="ANY",b="ANY"),
function(a,b,...) new("A",a=as.numeric(a),b=as.numeric(b),...)
)
setMethod("A", signature(a="ANY",b="missing"),
function(a,b,...) A(a,a,...) ## Calls the one above
)
etc.
In words:
1) validity should return a character in case of errors
2) default initializer usually does the job
3) define constructors as methods to allow different signatures and
conversions from other classes
4) If you derive your class from numeric, rather than add slots,
the performance will be much better and you will get default
behaviour of numeric, i.e.
setClass("A",
representatiom("numeric", b="numeric") etc
Dr Oleg Sklyar
Technology Group
Man Investments Ltd
+44 (0)20 7144 3803
osklyar at maninvestments.com
-----Original Message-----
From: r-devel-bounces at r-project.org
[mailto:r-devel-bounces at r-project.org] On Behalf Of
cgenolin at u-paris10.fr
Sent: 02 May 2008 15:41
To: r-devel at r-project.org
Subject: [Rd] S4: what to put in initialize, validity and constructor?
Hi the list,
I have some trouble using validity, intialize and the
constructor. More precisely, what should go where?
Here is a toy exemple (seams long, but the code is very simple):
I want to define an object with two slots a and b with the
properties that b will be either empty or the scare of a.
Example of valid object :
a= b=
a=2 b=
a=3 b=9
So I define my object and the validity function :
setClass(
"A",
representation(a="numeric",b="numeric"),
validity=function(object){
cat("Validity\n")
if(length(object at b)!=0){
if(length(object at a)==0){stop("Can not have empty
a and non emty b")}else{}
if(object at a^2!=object at b){stop("b is not the scare
of a")}else{}
}else{}
return(TRUE)
}
)
It works:
new("A")
new("A",a=2,b=4)
try(new("A",b=4))
new("A",a=2)
try(new("A",a=2,b=3))
Then I define the initialize function. When b is givent but
not a, the initialise function set a to sqrt(b).
setMethod(
"initialize",
"A",
function(.Object,a,b){
if(missing(a)&!missing(b)){
.Object at b <- b
.Object at a <- sqrt(b)
}else{}
if(!missing(a)&missing(b)){
.Object at a <- a
}else{}
if(!missing(a)&!missing(b)){
.Object at a <- a
.Object at b <- b
}else{}
validObject(.Object)
return(.Object)
}
)
It is fine:
new("A")
new("A",a=2,b=4)
new("A",b=9)
new("A",a=2)
try(new("A",a=2,b=3))
Then I want to set the constructor
A <- function(a,b){
return(new("A",a,b))
}
But this does not work:
A()
A(a=2,b=4)
A(b=9)
A(a=2)
The following does not work either:
A <- function(a=numeric(),b=numeric()){
return(new("A",a,b))
}
A()
A(a=2,b=4)
A(b=9)
A(a=2)
So is there a way to define the constructor A without dealing
again with all the missing&missing staff like in initialize?
Christophe