On Wed, Aug 22, 2012 at 4:47 PM, Steve Lianoglou <
mailinglist.honeypot@gmail.com> wrote:

> Hi,
>
> And since we're already getting pretty deep into the woods, I guess it
> can't hurt to keep going:
>
> On Wed, Aug 22, 2012 at 4:11 PM, Kasper Daniel Hansen
> <kasperdanielhansen@gmail.com> wrote:
> > Martin has a great technical explanation.
> >
> > A briefer explanation is the following.
> >
> > 'We' used to use an initialize method to construct new objects, like
> >   new("ExpressionSet", exprs = MATRIX)
> >
> > This paradigm is used in a number of packages, including Biobase.
> >
> > 'We' later realized - for reasons Martin explains below - that this is
> prone
> > to failure and should not be used.  However, you can still find tons of
> code
> > using it - for legacy reasons.
> >
> > In general, you should not define the initialize method, you should set a
> > prototype when you define the class and you should write an explicit
> > constructor, like
> >   ExpressionSet <- function() {}
>
> With the exception when your class has slots that are environments.
>
> If it's true that some things will still call new("YourClass", ...)
> that aren't your constructor, then you will be surprised:
>
> setClass("A", representation=representation(cache="environment"),
> prototype=prototype(cache=new.env()))
> ctr <- function(cache=new.env()) new("A", cache=cache)
>
> ## This is the behavior you probably expect:
> a = ctr()
> b = ctr()
> a@cache[['a']] = 1
> b@cache[['a']]
> NULL
>
> ## This isn't
> y = new("A")
> z = new("A")
> y@cache[['a']] = 1
> z@cache[['a']]
> [1] 1    ## Woops!
>
>
> But if you set an appropriate initialize method:
>
> setMethod(initialize, "A", function(.Object, ..., cache=new.env()) {
>   .Object@cache <- cache
>   callNextMethod(.Object, ...)
> })
>
> All is well:
> y = new("A")
> z = new("A")
> y@cache[['a']] = 1
> z@cache[['a']]
> NULL
>

This is of course true, but there are also the many reasons Martin outlined
for why using the initialize method is not that great.  I mean, of course
there are advantages to the initialize method - this is after all why it
was used and recommended for years in Bioconductor.

If you use a class that has an explicit constructor, you should use that
constructor, period.  That you will mess up your objects by not doing that,
ought to be self-evident.  This is kind of the same as the fact that for
for many classes it is possible to mess them up by directly assigning weird
things to their slots (remember that validObject is not always called all
the time, per default).

Kasper



>
> I think ReferenceClasses replaces (most(?)) of the use cases that I
> use the `cache` idiom for, although I'm not sure about the gotchas
> with them because I haven't tried to grok RefClasses yet.
>
> Still ... thought I'd point this out (I think it was actually one of
> you two, who must have alerted me to this years ago (perhaps on
> R-devel)).
>
> -steve
>
> --
> Steve Lianoglou
> Graduate Student: Computational Systems Biology
>  | Memorial Sloan-Kettering Cancer Center
>  | Weill Medical College of Cornell University
> Contact Info: http://cbio.mskcc.org/~lianos/contact
>

	[[alternative HTML version deleted]]

