On 01/10/2012 11:47 AM, Keith Weintraub wrote:> Folks,
>
> My object oriented background is in Java and C++. I am a novice to using
S4/object-oriented coding in R but not to R. Below is an example that I found
that I have expanded on.
>
> I am not getting how "prototype" and "initialize" work
together, if at all.
>
> Here is output from a short "session"
>
>> setClass("xx",
> + representation(a="numeric", b ="numeric"),
> + prototype(a=33, b = 333)
> + )
> [1] "xx"
>>
>> #setMethod("initialize", "xx",
function(.Object){.Object})
>>
>> setMethod("initialize", "xx",
> + function(.Object, b) {
> + .Object at b<-b
> + .Object at a<-b^2
> + .Object
> + }
> + )
> [1] "initialize"
>>
>> new("xx", 3)
> An object of class "xx"
> Slot "a":
> [1] 9
>
> Slot "b":
> [1] 3
>
>>
>> new("xx")
> Error in .local(.Object, ...) : argument "b" is missing, with no
default
Hi Keith --
This might be a good place to start, setting aside prototype for the moment.
You'd like new("xx") to work. This means that all arguments to
initialize need to have a default value. You'd also like new("xx",
new("xx")) to work, because it's advertised as a copy constructor
(a
slightly loose interpretation of ?new, which says for the ... argument
'Unnamed arguments must be objects from classes that this class
extends'). An appropriate initialize method is
setMethod(initialize, "xx", function(.Object, ..., b=2) {
callNextMethod(.Object, ..., b=b)
})
For instance,
> setClass("xx", representation(a="numeric",
b="numeric"))
> new("xx")
An object of class "xx"
Slot "a":
numeric(0)
Slot "b":
[1] 2
> new("xx", new("xx", a=1))
An object of class "xx"
Slot "a":
[1] 1
Slot "b":
[1] 2
> new("xx", new("xx", a=1), a=2, b=3)
An object of class "xx"
Slot "a":
[1] 2
Slot "b":
[1] 3
with the basic initializer out of the way, you could introduce a prototype
setClass("xx",
representation(a="numeric", b="numeric"),
prototype(a=-1, b=-2))
> new("xx")
An object of class "xx"
Slot "a":
[1] -1
Slot "b":
[1] 2
which shows that the prototype and initializer are playing well together
(for slot 'a') and that the initialize method is over-riding the
prototype (for slot 'b').
One could provide a default value to b in the initializer that is
derived from the prototype, which is used to populate .Object
setMethod(initialize, "xx", function(.Object, ..., b=.Object at b) {
callNextMethod(.Object, ..., b=b)
})
with
> new("xx", a=1)
An object of class "xx"
Slot "a":
[1] 1
Slot "b":
[1] -2
e.g., maybe you want to check user input and the check is expensive...
setMethod(initialize, "xx", function(.Object, ..., b=.Object at b) {
if (!missing(b))
## check user input, expensive
Sys.sleep(2)
callNextMethod(.Object, ..., b=b)
})
Maybe a slightly more common case is to provide a prototype for one slot
(e.g., for internal business, not the user) with initialize taking care
of others.
It is often the case that you'd like a constructor
xx <- function(a=-1, b=-2, ...)
new("xx", a=a, b=b, ...)
which is nicer for the end user, documents the necessary arguments,
frees one to separately implement the constructor vs. copy-constructor,
etc. Neither prototype nor initialize method would be implemented here,
leaving all the cleverness to the defaults.
One other thing is that the prototype must create a valid object; this
prototype allows R to produce invalid instances:
setClass("Abs", representation(x="numeric"),
prototype(x=-1),
validity=function(object) if (any(object at x < 0)) "oops"
else TRUE)
> a = new("Abs")
An object of class "Abs"
Slot "x":
[1] -1
> validObject(a)
Error in validObject(a) : invalid class "Abs" object: oops
Not sure whether that helps, or is too much information...
Martin
>
> Any help you can provide would be greatly appreciated,
> Thanks,
> KW
>
> --
>
>
> [[alternative HTML version deleted]]
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
--
Computational Biology
Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109
Location: M1-B861
Telephone: 206 667-2793