[R] Can "prototype" and "initialize" coexist?

Martin Morgan mtmorgan at fhcrc.org
Wed Jan 11 00:22:28 CET 2012


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



More information about the R-help mailing list