S4 classes: referencing slots with other slots

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

S4 classes: referencing slots with other slots

A.J. Rossini
For those who suggest other ways to do this, I ALREADY HAVE ANOTHER
DESIGN SOLUTION, DESCRIBED AT THE END.

That being said, I want to know if it's possible to reference a slot
in an S4 class from another slot, i.e. I'd like to have the "self.*"
semantics of Python so that I can reuse a slot.  That is, for various
reasons it would be nice to be able to do something like:

setClass("fooWfcn",
         representation(dat1="vector",
                        dat2="vector",
                        fn1="function",
                        fn2="function"),
         prototype=list(dat1=0:10,
           dat2=10:20,
           fn1=function(x) { return(x - mean(self.dat1)) },
           fn2=function() { mean(self.dat2) }))

and in the context of

foo <- new("fooWfcn")

have self.dat2 refer to foo@dat2, etc (I.e. in an instantiated object,
have the reference be within the object).

One could easily imagine doing this on the fly, as well, during the "new" call.

 I've looked this up in a number of books, on-line talks/papers, etc,
but havn't managed to find the right page describing it as possible or
impossible.  I think it is the latter (impossible), since one could
easily end up with a nasty self-referencing infinite loop (fn1
refering to fn2 refering to fn1).  If it's the former, I'd be
interested in knowing about it.

Anyway, here's the DESIGN SOLUTION: write methods which do the
appropriate "combination".

Critique:

pro - it works, it's simple, and I've already done it.

con - for the problem I'm looking at, it's not quite so clean, adding
one more layer of indirection that in Python or CLOS I'd not need,
multiplied by a fair number of subclasses.

best,
-tony

[hidden email]
Muttenz, Switzerland.
"Commit early,commit often, and commit in a repository from which we can easily
roll-back your mistakes" (AJR, 4Jan05).

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
Reply | Threaded
Open this post in threaded view
|

Re: S4 classes: referencing slots with other slots

Gabor Grothendieck
Although this does not answer your question regarding how
to do it in S4, it is simple to do with the proto package.

This creates a fooWfcn proto object and then two child
proto objects of it.  Here foo inherits dat1 from fooWfcn
but foo2 has its own dat1 which overrides the dat1 in
its parent.

library(proto)
fooWfcn <- proto(dat1 = 1:10, dat2 = 10:20,
        fn1 = function(., x) x - mean(.$dat1),
        fn2 = function(., x) mean(.$dat2))

foo <- fooWfcn$proto()
foo$fn1(0) # -5.5

foo2 <- fooWfcn$proto(dat1 = 11:20)
foo2$fn1(0) # -15.5



On 12/29/05, A.J. Rossini <[hidden email]> wrote:

> For those who suggest other ways to do this, I ALREADY HAVE ANOTHER
> DESIGN SOLUTION, DESCRIBED AT THE END.
>
> That being said, I want to know if it's possible to reference a slot
> in an S4 class from another slot, i.e. I'd like to have the "self.*"
> semantics of Python so that I can reuse a slot.  That is, for various
> reasons it would be nice to be able to do something like:
>
> setClass("fooWfcn",
>         representation(dat1="vector",
>                        dat2="vector",
>                        fn1="function",
>                        fn2="function"),
>         prototype=list(dat1=0:10,
>           dat2=10:20,
>           fn1=function(x) { return(x - mean(self.dat1)) },
>           fn2=function() { mean(self.dat2) }))
>
> and in the context of
>
> foo <- new("fooWfcn")
>
> have self.dat2 refer to foo@dat2, etc (I.e. in an instantiated object,
> have the reference be within the object).
>
> One could easily imagine doing this on the fly, as well, during the "new" call.
>
>  I've looked this up in a number of books, on-line talks/papers, etc,
> but havn't managed to find the right page describing it as possible or
> impossible.  I think it is the latter (impossible), since one could
> easily end up with a nasty self-referencing infinite loop (fn1
> refering to fn2 refering to fn1).  If it's the former, I'd be
> interested in knowing about it.
>
> Anyway, here's the DESIGN SOLUTION: write methods which do the
> appropriate "combination".
>
> Critique:
>
> pro - it works, it's simple, and I've already done it.
>
> con - for the problem I'm looking at, it's not quite so clean, adding
> one more layer of indirection that in Python or CLOS I'd not need,
> multiplied by a fair number of subclasses.
>
> best,
> -tony
>
> [hidden email]
> Muttenz, Switzerland.
> "Commit early,commit often, and commit in a repository from which we can easily
> roll-back your mistakes" (AJR, 4Jan05).
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html