S4 Classes and Initialize methods
On 02/05/2013 04:42 AM, Franck Doray wrote:
Hello,
I am trying to improve my skill on S4 classes. But there's something
strange (to me) happening with "initialize" methods. This is probably a
normal behaviour... but... something is unclear in my mind
I declare two classes, namely "A", and "B", which has a slot of type A. The
class "A" has an initialize method. What I do not understand is that the
Class A initialize-method is run when defining the Class B
Here is the code .
setClass("A",representation=representation(a="numeric"))
setMethod("initialize","A",function(.Object){cat("*** initialize A
***\n");return(.Object)}) [1] "initialize"
setClass("B",representation=representation(a="A",b="numeric"))
setClass("B",representation=representation(a="A",b="numeric"))
*** initialize A ***
Actually I do not understand the line *** initialize A ***. What the need to initialize A just in a (simple) definition of the class B?
Hi Franck --
That's probably not a useful question to ask, it's an implementation detail, but
I think because S4 classes have a prototype, and the default prototype for class
B's slot 'a' is constructed by calling new("A"):
> getClassDef("B")@prototype
<S4 Type Object>
attr(,"a")
An object of class "A"
Slot "a":
numeric(0)
attr(,"b")
numeric(0)
Maybe you came across this issue in some context? A couple of thoughts...
>> setMethod("initialize","A",function(.Object){cat("*** initialize A
> ***\n");return(.Object)})
> [1] "initialize"
Usually one wants to add '...' to the initialize method, and to callNextMethod()
inside initialize. This is because the default method fills in slots with named
arguments, so derived (perhaps even 'A') classes with simple slot initialization
do not need an initialize method at all. Thus
setMethod(initialize, "A", function(.Object, ...) {
message("initialize,A-method")
callNextMethod(.Object, ...)
})
C = setClass("C", contains="A", representation=representation(x="numeric"))
C(a=1:5, x=5:1)
with
> C(a=1:5, x=5:1)
initialize,A-method
An object of class "C"
Slot "x":
[1] 5 4 3 2 1
Slot "a":
[1] 1 2 3 4 5
(this uses a feature added in a relatively recent R, where setClass returns a
constructor which is basically a call to 'new').
> C
class generator function for class "C" from package '.GlobalEnv'
function (...)
new("C", ...)
Since my initialize,A-method doesn't actually do anything useful, I would
normally not implement it. If I were to write an initialize method, e.g,.
coercing 'x' to their absolute value, I'd write it so that (a) there is a
default value to 'x', so that new("A") with no arguments works and (b) make sure
that the argument 'x' came after ..., so that unnamed arguments are used in the
initialize method's copy construction mode. I try to illustrate this below
A <- setClass("A",representation=representation(a="numeric"))
setMethod(initialize, "A", function(.Object, ..., a=numeric()) {
callNextMethod(.Object, ..., a=abs(a))
})
And then
> ## no-arg constructor
> A()
An object of class "A"
Slot "a":
numeric(0)
> ## constructor with arg
> (a1 = A(a=-(1:5)))
An object of class "A"
Slot "a":
[1] 1 2 3 4 5
> ## copy constructor
> initialize(a1, a=-(5:1))
An object of class "A"
Slot "a":
[1] 5 4 3 2 1
The above is with
> R.version.string
[1] "R Under development (unstable) (2013-02-02 r61819)"
Martin
Thanks in advance Franck [[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: Arnold Building M1 B861 Phone: (206) 667-2793