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@b<-b
+             .Object@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@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@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@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@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

______________________________________________
R-help@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.

Reply via email to